1
0

FluAzu.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. <?php
  2. /* $Id: FluAzu.php 3057 2007-05-27 13:06:39Z b4rt $ */
  3. /*******************************************************************************
  4. LICENSE
  5. This program is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License (GPL)
  7. as published by the Free Software Foundation; either version 2
  8. of the License, or (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. To read the license please visit http://www.gnu.org/copyleft/gpl.html
  14. *******************************************************************************/
  15. // states
  16. define('FLUAZU_STATE_NULL', 0); // null
  17. define('FLUAZU_STATE_RUNNING', 1); // running
  18. define('FLUAZU_STATE_ERROR', -1); // error
  19. /**
  20. * class FluAzu for integration of fluazu
  21. */
  22. class FluAzu
  23. {
  24. // public fields
  25. // state
  26. var $state = FLUAZU_STATE_NULL;
  27. // messages-array
  28. var $messages = array();
  29. // private fields
  30. // pid
  31. var $_pid = "";
  32. // some path-vars for FluAzu
  33. var $_pathDataDir = "";
  34. var $_pathCommandFile = "";
  35. var $_pathPidFile = "";
  36. var $_pathLogFile = "";
  37. var $_pathStatFile = "";
  38. var $_pathTransfers = "";
  39. var $_pathTransfersRun = "";
  40. var $_pathTransfersDel = "";
  41. // commands-array
  42. var $_commands = array();
  43. // =========================================================================
  44. // public static methods
  45. // =========================================================================
  46. /**
  47. * accessor for singleton
  48. *
  49. * @return FluAzu
  50. */
  51. function getInstance() {
  52. global $instanceFluAzu;
  53. // initialize if needed
  54. if (!isset($instanceFluAzu))
  55. FluAzu::initialize();
  56. return $instanceFluAzu;
  57. }
  58. /**
  59. * initialize FluAzu.
  60. */
  61. function initialize() {
  62. global $instanceFluAzu;
  63. // create instance
  64. if (!isset($instanceFluAzu))
  65. $instanceFluAzu = new FluAzu();
  66. }
  67. /**
  68. * accessor for state
  69. *
  70. * @return int
  71. */
  72. function getState() {
  73. global $instanceFluAzu;
  74. return (isset($instanceFluAzu))
  75. ? $instanceFluAzu->state
  76. : FLUAZU_STATE_NULL;
  77. }
  78. /**
  79. * getMessages
  80. *
  81. * @return array
  82. */
  83. function getMessages() {
  84. global $instanceFluAzu;
  85. return (isset($instanceFluAzu))
  86. ? $instanceFluAzu->messages
  87. : array();
  88. }
  89. /**
  90. * isRunning
  91. *
  92. * @return boolean
  93. */
  94. function isRunning() {
  95. global $instanceFluAzu;
  96. // initialize if needed
  97. if (!isset($instanceFluAzu))
  98. FluAzu::initialize();
  99. return $instanceFluAzu->instance_isRunning();
  100. }
  101. /**
  102. * start
  103. *
  104. * @return boolean
  105. */
  106. function start() {
  107. global $instanceFluAzu;
  108. // initialize if needed
  109. if (!isset($instanceFluAzu))
  110. FluAzu::initialize();
  111. return $instanceFluAzu->instance_start();
  112. }
  113. /**
  114. * stop
  115. */
  116. function stop() {
  117. global $instanceFluAzu;
  118. // initialize if needed
  119. if (!isset($instanceFluAzu))
  120. FluAzu::initialize();
  121. return $instanceFluAzu->instance_stop();
  122. }
  123. /**
  124. * getPid
  125. *
  126. * @return int with pid
  127. */
  128. function getPid() {
  129. global $instanceFluAzu;
  130. // initialize if needed
  131. if (!isset($instanceFluAzu))
  132. FluAzu::initialize();
  133. return $instanceFluAzu->instance_getPid();
  134. }
  135. /**
  136. * writes a message to the log
  137. *
  138. * @param $message
  139. * @param $withTS
  140. * @return boolean
  141. */
  142. function logMessage($message, $withTS = true) {
  143. global $instanceFluAzu;
  144. // initialize if needed
  145. if (!isset($instanceFluAzu))
  146. FluAzu::initialize();
  147. return $instanceFluAzu->instance_logMessage($message, $withTS);
  148. }
  149. /**
  150. * send command
  151. *
  152. * @param $command
  153. * @param $autosend
  154. * @return boolean
  155. */
  156. function addCommand($command, $autosend = false) {
  157. global $instanceFluAzu;
  158. // initialize if needed
  159. if (!isset($instanceFluAzu))
  160. FluAzu::initialize();
  161. return $instanceFluAzu->instance_addCommand($command, $autosend);
  162. }
  163. /**
  164. * send commands
  165. *
  166. * @return boolean
  167. */
  168. function sendCommands() {
  169. global $instanceFluAzu;
  170. // initialize if needed
  171. if (!isset($instanceFluAzu))
  172. FluAzu::initialize();
  173. return $instanceFluAzu->instance_sendCommands();
  174. }
  175. /**
  176. * del transfer
  177. *
  178. * @param $transfer
  179. * @return boolean
  180. */
  181. function delTransfer($transfer) {
  182. global $instanceFluAzu;
  183. // initialize if needed
  184. if (!isset($instanceFluAzu))
  185. FluAzu::initialize();
  186. return $instanceFluAzu->instance_delTransfer($transfer);
  187. }
  188. /**
  189. * transfer exists
  190. *
  191. * @param $transfer
  192. * @return boolean
  193. */
  194. function transferExists($transfer) {
  195. global $instanceFluAzu;
  196. // initialize if needed
  197. if (!isset($instanceFluAzu))
  198. FluAzu::initialize();
  199. return $instanceFluAzu->instance_transferExists($transfer);
  200. }
  201. /**
  202. * get status
  203. *
  204. * @return array
  205. */
  206. function getStatus() {
  207. global $instanceFluAzu;
  208. // initialize if needed
  209. if (!isset($instanceFluAzu))
  210. FluAzu::initialize();
  211. return $instanceFluAzu->instance_getStatus();
  212. }
  213. /**
  214. * get status-keys
  215. *
  216. * @return array
  217. */
  218. function getStatusKeys() {
  219. global $instanceFluAzu;
  220. // initialize if needed
  221. if (!isset($instanceFluAzu))
  222. FluAzu::initialize();
  223. return $instanceFluAzu->instance_getStatusKeys();
  224. }
  225. /**
  226. * set global upload rate
  227. *
  228. * @param $uprate
  229. * @param $autosend
  230. */
  231. function setRateUpload($uprate, $autosend = false) {
  232. global $instanceFluAzu;
  233. // initialize if needed
  234. if (!isset($instanceFluAzu))
  235. FluAzu::initialize();
  236. return $instanceFluAzu->instance_setRateUpload($uprate, $autosend);
  237. }
  238. /**
  239. * set global download rate
  240. *
  241. * @param $downrate
  242. * @param $autosend
  243. */
  244. function setRateDownload($downrate, $autosend = false) {
  245. global $instanceFluAzu;
  246. // initialize if needed
  247. if (!isset($instanceFluAzu))
  248. FluAzu::initialize();
  249. return $instanceFluAzu->instance_setRateDownload($downrate, $autosend);
  250. }
  251. /**
  252. * set a azu-setting
  253. *
  254. * @param $key
  255. * @param $val
  256. * @param $autosend
  257. */
  258. function setAzu($key, $val, $autosend = false) {
  259. global $instanceFluAzu;
  260. // initialize if needed
  261. if (!isset($instanceFluAzu))
  262. FluAzu::initialize();
  263. return $instanceFluAzu->instance_setAzu($key, $val, $autosend);
  264. }
  265. // =========================================================================
  266. // ctor
  267. // =========================================================================
  268. /**
  269. * ctor
  270. */
  271. function FluAzu() {
  272. global $cfg;
  273. // paths
  274. $this->_pathDataDir = $cfg["path"] . '.fluazu/';
  275. $this->_pathPidFile = $this->_pathDataDir . 'fluazu.pid';
  276. $this->_pathCommandFile = $this->_pathDataDir . 'fluazu.cmd';
  277. $this->_pathLogFile = $this->_pathDataDir . 'fluazu.log';
  278. $this->_pathStatFile = $this->_pathDataDir . 'fluazu.stat';
  279. $this->_pathTransfers = $this->_pathDataDir . 'cur/';
  280. $this->_pathTransfersRun = $this->_pathDataDir . 'run/';
  281. $this->_pathTransfersDel = $this->_pathDataDir . 'del/';
  282. // check path
  283. if (!checkDirectory($this->_pathDataDir)) {
  284. @error("fluazu-Main-Path does not exist and cannot be created or is not writable",
  285. "admin.php?op=serverSettings", "Server-Settings",
  286. array("path : ".$this->_pathDataDir)
  287. );
  288. }
  289. // check if fluazu running
  290. if ($this->instance_isRunning())
  291. $this->state = FLUAZU_STATE_RUNNING;
  292. }
  293. // =========================================================================
  294. // public methods
  295. // =========================================================================
  296. /**
  297. * instance_start
  298. *
  299. * @return boolean
  300. */
  301. function instance_start() {
  302. global $cfg;
  303. if ($this->state == FLUAZU_STATE_RUNNING) {
  304. AuditAction($cfg["constants"]["error"], "fluazu already started");
  305. return false;
  306. } else {
  307. // check the needed bins
  308. // python
  309. if (@file_exists($cfg['pythonCmd']) !== true) {
  310. $msg = "cannot start fluazu, specified python-binary does not exist: ".$cfg['pythonCmd'];
  311. AuditAction($cfg["constants"]["error"], $msg);
  312. array_push($this->messages , $msg);
  313. // Set the state
  314. $this->state = FLUAZU_STATE_ERROR;
  315. // return
  316. return false;
  317. }
  318. // start it
  319. $startCommand = "cd ".tfb_shellencode($cfg["docroot"]."bin/clients/fluazu/")."; HOME=".tfb_shellencode($cfg["path"]).";";
  320. $startCommand .= " export HOME;";
  321. $startCommand .= " nohup";
  322. $startCommand .= " ".$cfg["pythonCmd"]." -OO";
  323. $startCommand .= " fluazu.py";
  324. $startCommand .= " ".tfb_shellencode($cfg["path"]);
  325. $startCommand .= " ".tfb_shellencode($cfg["fluazu_host"]);
  326. $startCommand .= " ".tfb_shellencode($cfg["fluazu_port"]);
  327. $startCommand .= " ".tfb_shellencode($cfg["fluazu_secure"]);
  328. $startCommand .= ($cfg["fluazu_user"] == "")
  329. ? ' ""'
  330. : " ".tfb_shellencode($cfg["fluazu_user"]);
  331. $startCommand .= ($cfg["fluazu_pw"] == "")
  332. ? ' ""'
  333. : " ".tfb_shellencode($cfg["fluazu_pw"]);
  334. $startCommand .= " 1>> ".tfb_shellencode($this->_pathLogFile);
  335. $startCommand .= " 2>> ".tfb_shellencode($this->_pathLogFile);
  336. $startCommand .= " &";
  337. // log the command
  338. $this->instance_logMessage("executing command : \n".$startCommand."\n", true);
  339. // exec
  340. $result = exec($startCommand);
  341. // check if fluazu could be started
  342. $loop = true;
  343. $maxLoops = 125;
  344. $loopCtr = 0;
  345. $started = false;
  346. while ($loop) {
  347. @clearstatcache();
  348. if (file_exists($this->_pathStatFile)) {
  349. $started = true;
  350. $loop = false;
  351. } else {
  352. $loopCtr++;
  353. if ($loopCtr > $maxLoops)
  354. $loop = false;
  355. else
  356. usleep(200000); // wait for 0.2 seconds
  357. }
  358. }
  359. // check if started
  360. if ($started) {
  361. AuditAction($cfg["constants"]["admin"], "fluazu started");
  362. // Set the state
  363. $this->state = FLUAZU_STATE_RUNNING;
  364. // return
  365. return true;
  366. } else {
  367. AuditAction($cfg["constants"]["error"], "errors starting fluazu");
  368. // Set the state
  369. $this->state = FLUAZU_STATE_ERROR;
  370. // return
  371. return false;
  372. }
  373. }
  374. }
  375. /**
  376. * instance_stop
  377. */
  378. function instance_stop() {
  379. global $cfg;
  380. if ($this->state == FLUAZU_STATE_RUNNING) {
  381. AuditAction($cfg["constants"]["admin"], "Stopping fluazu");
  382. $this->instance_addCommand('q', true);
  383. // check if fluazu still running
  384. $maxLoops = 125;
  385. $loopCtr = 0;
  386. for (;;) {
  387. @clearstatcache();
  388. if ($this->instance_isRunning()) {
  389. $loopCtr++;
  390. if ($loopCtr > $maxLoops)
  391. return 0;
  392. else
  393. usleep(200000); // wait for 0.2 seconds
  394. } else {
  395. // Set the state
  396. $this->state = FLUAZU_STATE_NULL;
  397. // return
  398. return 1;
  399. }
  400. }
  401. return 0;
  402. } else {
  403. $msg = "errors stopping fluazu as was not running.";
  404. AuditAction($cfg["constants"]["error"], $msg);
  405. array_push($this->messages , $msg);
  406. // Set the state
  407. $this->state = FLUAZU_STATE_ERROR;
  408. return 0;
  409. }
  410. }
  411. /**
  412. * isRunning
  413. *
  414. * @return boolean
  415. */
  416. function instance_isRunning() {
  417. return file_exists($this->_pathPidFile);
  418. }
  419. /**
  420. * instance_getPid
  421. *
  422. * @return string with pid
  423. */
  424. function instance_getPid() {
  425. if ($this->_pid != "") {
  426. return $this->_pid;
  427. } else {
  428. $this->_pid = @rtrim(file_get_contents($this->_pathPidFile));
  429. return $this->_pid;
  430. }
  431. }
  432. /**
  433. * writes a message to the log
  434. *
  435. * @param $message
  436. * @param $withTS
  437. * @return boolean
  438. */
  439. function instance_logMessage($message, $withTS = true) {
  440. return $this->_log($this->_pathLogFile, $message, $withTS);
  441. }
  442. /**
  443. * send command
  444. *
  445. * @param $command
  446. * @param $autosend
  447. * @return boolean
  448. */
  449. function instance_addCommand($command, $autosend = false) {
  450. if (!isset($this->_commands))
  451. $this->_commands = array();
  452. if ((!in_array($command, $this->_commands)) && (strlen($command) > 0)) {
  453. array_push($this->_commands, $command);
  454. return ($autosend)
  455. ? $this->sendCommands()
  456. : true;
  457. } else {
  458. return false;
  459. }
  460. }
  461. /**
  462. * send commands
  463. *
  464. * @return boolean
  465. */
  466. function instance_sendCommands() {
  467. if (($this->state == FLUAZU_STATE_RUNNING) && (!empty($this->_commands))) {
  468. $content = implode("\n", $this->_commands)."\n";
  469. $this->_commands = array();
  470. return $this->_writeCommandFile($content);
  471. } else {
  472. return false;
  473. }
  474. }
  475. /**
  476. * del transfer
  477. *
  478. * @param $transfer
  479. * @return boolean
  480. */
  481. function instance_delTransfer($transfer) {
  482. global $cfg;
  483. if ($this->state == FLUAZU_STATE_RUNNING) {
  484. // debug-log
  485. if ($cfg['debuglevel'] > 0)
  486. AuditAction($cfg["constants"]["debug"], "fluazu deleting transfer ".$transfer);
  487. // write file
  488. $file = $this->_pathTransfersDel.$transfer;
  489. $handle = false;
  490. $handle = @fopen($file, "w");
  491. if (!$handle) {
  492. $msg = "cannot open file ".$file." for writing.";
  493. array_push($this->messages , $msg);
  494. AuditAction($cfg["constants"]["error"], "FluAzu instance_delTransfer-Error : ".$msg);
  495. return false;
  496. }
  497. $result = @fwrite($handle, $cfg['user']);
  498. @fclose($handle);
  499. if ($result === false) {
  500. $msg = "cannot write content to file ".$file.".";
  501. array_push($this->messages , $msg);
  502. AuditAction($cfg["constants"]["error"], "FluAzu instance_delTransfer-Error : ".$msg);
  503. return false;
  504. }
  505. // send reload-command
  506. $this->instance_addCommand('r', true);
  507. // wait until file is gone (fluazu has processed the request)
  508. $maxLoops = 75;
  509. $loopCtr = 0;
  510. for (;;) {
  511. @clearstatcache();
  512. if ($this->instance_transferExists($transfer)) {
  513. $loopCtr++;
  514. if ($loopCtr > $maxLoops) {
  515. $msg = "fluazu did not delete transfer ".$transfer." after ".($maxLoops / 5)." seconds, giving up";
  516. array_push($this->messages , $msg);
  517. AuditAction($cfg["constants"]["error"], "FluAzu instance_delTransfer-Error : ".$msg);
  518. return false;
  519. } else {
  520. usleep(200000); // wait for 0.2 seconds
  521. }
  522. } else {
  523. // give fluazu another second before returning
  524. sleep(1);
  525. // return
  526. return true;
  527. }
  528. }
  529. } else {
  530. $msg = "fluazu not running, cannot delete transfer ".$transfer;
  531. AuditAction($cfg["constants"]["error"], $msg);
  532. array_push($this->messages , $msg);
  533. // Set the state
  534. $this->state = FLUAZU_STATE_ERROR;
  535. return false;
  536. }
  537. }
  538. /**
  539. * transfer exists
  540. *
  541. * @param $transfer
  542. * @return boolean
  543. */
  544. function instance_transferExists($transfer) {
  545. return file_exists($this->_pathTransfers.$transfer);
  546. }
  547. /**
  548. * get status
  549. *
  550. * @return array
  551. */
  552. function instance_getStatus() {
  553. $keys = $this->instance_getStatusKeys();
  554. $retVal = array();
  555. if ($this->state == FLUAZU_STATE_RUNNING) {
  556. $data = @file_get_contents($this->_pathStatFile);
  557. $content = @explode("\n", $data);
  558. $count = count($keys);
  559. if (is_array($content) && (count($content) >= $count)) {
  560. $content = array_map('trim', $content);
  561. for ($i = 0; $i < $count; $i++)
  562. $retVal[$keys[$i]] = $content[$i];
  563. return $retVal;
  564. }
  565. }
  566. foreach ($keys as $key)
  567. $retVal[$key] = 0;
  568. return $retVal;
  569. }
  570. /**
  571. * get status-keys
  572. *
  573. * @return array
  574. */
  575. function instance_getStatusKeys() {
  576. return array(
  577. 'azu_host',
  578. 'azu_port',
  579. 'azu_version',
  580. 'CORE_PARAM_INT_MAX_ACTIVE',
  581. 'CORE_PARAM_INT_MAX_ACTIVE_SEEDING',
  582. 'CORE_PARAM_INT_MAX_CONNECTIONS_GLOBAL',
  583. 'CORE_PARAM_INT_MAX_CONNECTIONS_PER_TORRENT',
  584. 'CORE_PARAM_INT_MAX_DOWNLOAD_SPEED_KBYTES_PER_SEC',
  585. 'CORE_PARAM_INT_MAX_DOWNLOADS',
  586. 'CORE_PARAM_INT_MAX_UPLOAD_SPEED_KBYTES_PER_SEC',
  587. 'CORE_PARAM_INT_MAX_UPLOAD_SPEED_SEEDING_KBYTES_PER_SEC',
  588. 'CORE_PARAM_INT_MAX_UPLOADS',
  589. 'CORE_PARAM_INT_MAX_UPLOADS_SEEDING'
  590. );
  591. }
  592. /**
  593. * set global upload rate
  594. *
  595. * @param $uprate
  596. * @param $autosend
  597. */
  598. function instance_setRateUpload($uprate, $autosend = false) {
  599. $this->instance_setAzu('CORE_PARAM_INT_MAX_UPLOAD_SPEED_KBYTES_PER_SEC', $uprate, $autosend);
  600. }
  601. /**
  602. * set global download rate
  603. *
  604. * @param $downrate
  605. * @param $autosend
  606. */
  607. function instance_setRateDownload($downrate, $autosend = false) {
  608. $this->instance_setAzu('CORE_PARAM_INT_MAX_DOWNLOAD_SPEED_KBYTES_PER_SEC', $downrate, $autosend);
  609. }
  610. /**
  611. * set a azu-setting
  612. *
  613. * @param $key
  614. * @param $val
  615. * @param $autosend
  616. */
  617. function instance_setAzu($key, $val, $autosend = false) {
  618. $this->instance_addCommand('s'.$key.':'.$val, $autosend);
  619. }
  620. // =========================================================================
  621. // private methods
  622. // =========================================================================
  623. /**
  624. * log a message
  625. *
  626. * @param $logFile
  627. * @param $message
  628. * @param $withTS
  629. * @return boolean
  630. */
  631. function _log($logFile, $message, $withTS = false) {
  632. $content = "";
  633. if ($withTS)
  634. $content .= @date("[Y/m/d - H:i:s]");
  635. $content .= '[FRONTEND] ';
  636. $content .= $message;
  637. $fp = false;
  638. $fp = @fopen($logFile, "a+");
  639. if (!$fp)
  640. return false;
  641. $result = @fwrite($fp, $content);
  642. @fclose($fp);
  643. if ($result === false)
  644. return false;
  645. return true;
  646. }
  647. /**
  648. * write the command-file
  649. *
  650. * @param $content
  651. * @return boolean
  652. */
  653. function _writeCommandFile($content) {
  654. global $cfg;
  655. $handle = false;
  656. $handle = @fopen($this->_pathCommandFile, "w");
  657. if (!$handle) {
  658. $msg = "cannot open command-file ".$this->_pathCommandFile." for writing.";
  659. array_push($this->messages , $msg);
  660. AuditAction($cfg["constants"]["error"], "FluAzu _writeCommandFile-Error : ".$msg);
  661. return false;
  662. }
  663. $result = @fwrite($handle, $content);
  664. @fclose($handle);
  665. if ($result === false) {
  666. $msg = "cannot write content to command-file ".$this->_pathCommandFile.".";
  667. array_push($this->messages , $msg);
  668. AuditAction($cfg["constants"]["error"], "FluAzu _writeCommandFile-Error : ".$msg);
  669. return false;
  670. }
  671. return true;
  672. }
  673. }
  674. ?>