1
0

FluxCLI.php 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465
  1. <?php
  2. /* $Id: FluxCLI.php 3260 2007-11-07 22:25:17Z warion $ */
  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. // defines
  16. define('_DUMP_DELIM', '*');
  17. preg_match('|.*\s(\d+)\s.*|', '$Revision: 3260 $', $revisionMatches);
  18. define('_REVISION_FLUXCLI', $revisionMatches[1]);
  19. /**
  20. * FluxCLI
  21. */
  22. class FluxCLI
  23. {
  24. // public fields
  25. // name
  26. var $name = "FluxCLI";
  27. // private fields
  28. // script
  29. var $_script = "fluxcli.php";
  30. // action
  31. var $_action = "";
  32. // args
  33. var $_args = array();
  34. var $_argc = 0;
  35. // arg-errors-array
  36. var $_argErrors = array();
  37. // =========================================================================
  38. // public static methods
  39. // =========================================================================
  40. /**
  41. * accessor for singleton
  42. *
  43. * @return FluxCLI
  44. */
  45. function getInstance() {
  46. global $instanceFluxCLI;
  47. return (isset($instanceFluxCLI))
  48. ? $instanceFluxCLI
  49. : false;
  50. }
  51. /**
  52. * getAction
  53. *
  54. * @return string
  55. */
  56. function getAction() {
  57. global $instanceFluxCLI;
  58. return (isset($instanceFluxCLI))
  59. ? $instanceFluxCLI->_action
  60. : "";
  61. }
  62. /**
  63. * getArgs
  64. *
  65. * @return array
  66. */
  67. function getArgs() {
  68. global $instanceFluxCLI;
  69. return (isset($instanceFluxCLI))
  70. ? $instanceFluxCLI->_args
  71. : array();
  72. }
  73. /**
  74. * process a request
  75. *
  76. * @param $args
  77. * @return mixed
  78. */
  79. function processRequest($args) {
  80. global $instanceFluxCLI;
  81. // create new instance
  82. $instanceFluxCLI = new FluxCLI($args);
  83. // call instance-method
  84. return (!$instanceFluxCLI)
  85. ? false
  86. : $instanceFluxCLI->instance_processRequest();
  87. }
  88. // =========================================================================
  89. // ctor
  90. // =========================================================================
  91. /**
  92. * do not use direct, use the public static methods !
  93. *
  94. * @param $args
  95. * @return FluxCLI
  96. */
  97. function FluxCLI($args) {
  98. global $cfg;
  99. // set user-var
  100. $cfg["user"] = GetSuperAdmin();
  101. // set admin-var
  102. $cfg['isAdmin'] = true;
  103. // set user-agent
  104. $cfg['user_agent'] = $this->name."/" . _REVISION_FLUXCLI;
  105. $_SERVER['HTTP_USER_AGENT'] = $this->name."/" . _REVISION_FLUXCLI;
  106. // parse args and set fields
  107. $argCount = count($args);
  108. if ($argCount < 1) {
  109. // invalid args
  110. $this->_outputError("invalid args.\n");
  111. return false;
  112. }
  113. $this->_script = basename($args[0]);
  114. $this->_action = (isset($args[1])) ? $args[1] : "";
  115. if ($argCount > 2) {
  116. $prm = array_splice($args, 2);
  117. $this->_args = array_map('trim', $prm);
  118. $this->_argc = count($this->_args);
  119. } else {
  120. $this->_args = array();
  121. $this->_argc = 0;
  122. }
  123. }
  124. // =========================================================================
  125. // public methods
  126. // =========================================================================
  127. /**
  128. * process a request
  129. *
  130. * @return mixed
  131. */
  132. function instance_processRequest() {
  133. global $cfg;
  134. // action-switch
  135. switch ($this->_action) {
  136. /* netstat */
  137. case "netstat":
  138. return $this->_netstat();
  139. /* transfers */
  140. case "transfers":
  141. return $this->_transfers();
  142. /* start */
  143. case "start":
  144. if (empty($this->_args[0])) {
  145. array_push($this->_argErrors, "missing argument: name of transfer. (extra-arg 1)");
  146. break;
  147. } else {
  148. return $this->_transferStart(
  149. $this->_args[0],
  150. (isset($this->_args[1])) ? $this->_args[1] : "",
  151. ($this->_argc > 2) ? array_slice($this->_args, 2) : array()
  152. );
  153. }
  154. /* stop */
  155. case "stop":
  156. if (empty($this->_args[0])) {
  157. array_push($this->_argErrors, "missing argument: name of transfer. (extra-arg 1)");
  158. break;
  159. } else {
  160. return $this->_transferStop($this->_args[0]);
  161. }
  162. /* enqueue */
  163. case "enqueue":
  164. if (empty($this->_args[0])) {
  165. array_push($this->_argErrors, "missing argument: name of transfer. (extra-arg 1)");
  166. break;
  167. } else {
  168. return $this->_transferEnqueue($this->_args[0]);
  169. }
  170. /* dequeue */
  171. case "dequeue":
  172. if (empty($this->_args[0])) {
  173. array_push($this->_argErrors, "missing argument: name of transfer. (extra-arg 1)");
  174. break;
  175. } else {
  176. return $this->_transferDequeue($this->_args[0]);
  177. }
  178. /* reset */
  179. case "reset":
  180. if (empty($this->_args[0])) {
  181. array_push($this->_argErrors, "missing argument: name of transfer. (extra-arg 1)");
  182. break;
  183. } else {
  184. return $this->_transferReset($this->_args[0]);
  185. }
  186. /* delete */
  187. case "delete":
  188. if (empty($this->_args[0])) {
  189. array_push($this->_argErrors, "missing argument: name of transfer. (extra-arg 1)");
  190. break;
  191. } else {
  192. return $this->_transferDelete($this->_args[0]);
  193. }
  194. /* wipe */
  195. case "wipe":
  196. if (empty($this->_args[0])) {
  197. array_push($this->_argErrors, "missing argument: name of transfer. (extra-arg 1)");
  198. break;
  199. } else {
  200. return $this->_transferWipe($this->_args[0]);
  201. }
  202. /* start-all */
  203. case "start-all":
  204. return $this->_transfersStart(
  205. (isset($this->_args[0])) ? $this->_args[0] : "",
  206. ($this->_argc > 1) ? array_slice($this->_args, 1) : array()
  207. );
  208. /* resume-all */
  209. case "resume-all":
  210. return $this->_transfersResume(
  211. (isset($this->_args[0])) ? $this->_args[0] : "",
  212. ($this->_argc > 1) ? array_slice($this->_args, 1) : array()
  213. );
  214. /* stop-all */
  215. case "stop-all":
  216. return $this->_transfersStop();
  217. /* tset */
  218. case "tset":
  219. if ($this->_argc < 3) {
  220. array_push($this->_argErrors, "missing argument(s) for tset.");
  221. break;
  222. } else {
  223. return $this->_tset(
  224. $this->_args[0], $this->_args[1], $this->_args[2],
  225. (isset($this->_args[3])) ? $this->_args[3] : "s"
  226. );
  227. }
  228. /* inject */
  229. case "inject":
  230. if ($this->_argc < 2) {
  231. array_push($this->_argErrors, "missing argument(s) for inject.");
  232. break;
  233. } else {
  234. return $this->_inject(
  235. $this->_args[0], $this->_args[1],
  236. (isset($this->_args[2])) ? $this->_args[2] : "",
  237. ($this->_argc > 3) ? array_slice($this->_args, 3) : array()
  238. );
  239. }
  240. /* watch */
  241. case "watch":
  242. if ($this->_argc < 2) {
  243. array_push($this->_argErrors, "missing argument(s) for watch.");
  244. break;
  245. } else {
  246. return $this->_watch(
  247. $this->_args[0], $this->_args[1],
  248. (isset($this->_args[2])) ? $this->_args[2] : "ds",
  249. ($this->_argc > 3) ? array_slice($this->_args, 3) : array()
  250. );
  251. }
  252. /* rss */
  253. case "rss":
  254. if ($this->_argc < 4) {
  255. array_push($this->_argErrors, "missing argument(s) for rss.");
  256. break;
  257. } else {
  258. return $this->_rss(
  259. $this->_args[0], $this->_args[1],
  260. $this->_args[2], $this->_args[3],
  261. (isset($this->_args[4])) ? $this->_args[4] : ""
  262. );
  263. }
  264. /* xfer */
  265. case "xfer":
  266. if (empty($this->_args[0])) {
  267. array_push($this->_argErrors, "missing argument: time-delta of xfer to use : (all/total/month/week/day) (extra-arg 1)");
  268. break;
  269. } else {
  270. return $this->_xfer($this->_args[0]);
  271. }
  272. /* repair */
  273. case "repair":
  274. return $this->_repair();
  275. /* maintenance */
  276. case "maintenance":
  277. return $this->_maintenance(((isset($this->_args[0])) && (strtolower($this->_args[0]) == "true")) ? true : false);
  278. /* dump */
  279. case "dump":
  280. if (empty($this->_args[0])) {
  281. array_push($this->_argErrors, "missing argument: type. (settings/users) (extra-arg 1)");
  282. break;
  283. } else {
  284. return $this->_dump($this->_args[0]);
  285. }
  286. /* filelist */
  287. case "filelist":
  288. printFileList((empty($this->_args[0])) ? $cfg['docroot'] : $this->_args[0], 1, 1);
  289. return true;
  290. /* checksums */
  291. case "checksums":
  292. printFileList((empty($this->_args[0])) ? $cfg['docroot'] : $this->_args[0], 2, 1);
  293. return true;
  294. /* version */
  295. case "version":
  296. case "-version":
  297. case "--version":
  298. case "-v":
  299. return $this->_printVersion();
  300. /* help */
  301. case "help":
  302. case "-help":
  303. case "--help":
  304. case "-h":
  305. default:
  306. return $this->_printUsage();
  307. }
  308. // help
  309. return $this->_printUsage();
  310. }
  311. // =========================================================================
  312. // private methods -- options parsing helpers
  313. // =========================================================================
  314. /**
  315. * Parse a list of options, with optional extra-args.
  316. * Returns false in case of error, e.g. missing extra-arg
  317. * (error already reported via $this->_outputError).
  318. *
  319. * Example:
  320. * _parseOptions(
  321. * array( // $desc: array of possible options with number of extra-args.
  322. * 'd' => 0, // Options 'd' and 's' take no extra-arg.
  323. * 's' => 0,
  324. * 'p' => 1, // Option 'p' takes one extra-arg.
  325. * 'x' => 2 // Option 'x' takes two extra-args.
  326. * ),
  327. * 'spx', // $options
  328. * array('profname', 'x1', 'x2') // $extra
  329. * ) === array(
  330. * 's' => array(), // Option 's' was found, no extra-arg.
  331. * 'p' => array('profname'), // Option 'p' was found, its extra-arg's value was 'profname'.
  332. * 'x' => array('x1', 'x2') // Option 'x' was found, its extra-args' values were 'x1' and 'x2'.
  333. * )
  334. *
  335. * @param array $desc
  336. * @param string $options
  337. * @param array $extra
  338. * @return array
  339. */
  340. function _parseOptions($desc, $options = '', $extra = array()) {
  341. $return = array();
  342. // This preg_split merely does a str_split, but works on PHP4.
  343. foreach (preg_split('/(?<=.)(?=.)/s', $options) as $option) {
  344. // Unknown option, ignore it.
  345. if (!array_key_exists($option, $desc))
  346. continue;
  347. $needed = $desc[$option];
  348. $found = array();
  349. // Option needs at least one extra-arg, ensure there are enough and load it/them.
  350. if ($needed > 0) {
  351. if (!is_array($extra) || count($extra) < $needed) {
  352. $this->_outputError("missing extra argument(s) for option '".$option."'.\n");
  353. return false;
  354. }
  355. for ($i = 0; $i < $needed; $i++)
  356. array_push($found, array_shift($extra));
  357. }
  358. $return[$option] = $found;
  359. }
  360. return $return;
  361. }
  362. /**
  363. * Build a list of options for a new function call, by passing
  364. * thru some options from the current call (works on an options
  365. * set, returned previously by $this->_parseOptions).
  366. *
  367. * Example:
  368. * _buildOptions(
  369. * 'spx', // $options: list of options to pass-thru
  370. * array( // $optionsSet: options of current call
  371. * 'd' => array(),
  372. * 's' => array(),
  373. * 'x' => array('x1', 'x2'),
  374. * 'p' => array('profname')
  375. * )
  376. * ) === array(
  377. * 'sxp', // $options for new call // The three options 's', 'p' and 'x' are
  378. * array('x1', 'x2', 'profname') // $extra for new call // forwarded, with their extra-args.
  379. * )
  380. *
  381. * @param string $options
  382. * @param array $optionsSet
  383. * @return array
  384. */
  385. function _buildOptions($options, $optionsSet) {
  386. $returnOptions = '';
  387. $returnExtra = array();
  388. // Iterate on current call's options.
  389. foreach ($optionsSet as $option => $extra) {
  390. // If this option should be passed thru to next call, add it.
  391. if (strpos($options, $option) !== false) {
  392. $returnOptions .= $option;
  393. $returnExtra = array_merge($returnExtra, $extra);
  394. }
  395. }
  396. return array($returnOptions, $returnExtra);
  397. }
  398. // =========================================================================
  399. // private methods
  400. // =========================================================================
  401. /**
  402. * Print Net Stat
  403. *
  404. * @return mixed
  405. */
  406. function _netstat() {
  407. global $cfg;
  408. echo $cfg['_ID_CONNECTIONS'].":\n";
  409. echo netstatConnectionsSum()."\n";
  410. echo $cfg['_ID_PORTS'].":\n";
  411. echo netstatPortList();
  412. echo $cfg['_ID_HOSTS'].":\n";
  413. echo netstatHostList();
  414. return true;
  415. }
  416. /**
  417. * Show Transfers
  418. *
  419. * @return mixed
  420. */
  421. function _transfers() {
  422. global $cfg;
  423. // print out transfers
  424. echo "Transfers:\n";
  425. $transferHeads = getTransferListHeadArray();
  426. echo "* Name * ".implode(" * ", $transferHeads)."\n";
  427. $transferList = getTransferListArray();
  428. foreach ($transferList as $transferAry)
  429. echo "- ".implode(" - ", $transferAry)."\n";
  430. // print out stats
  431. echo "Server:\n";
  432. if (! array_key_exists("total_download", $cfg))
  433. $cfg["total_download"] = 0;
  434. if (! array_key_exists("total_upload", $cfg))
  435. $cfg["total_upload"] = 0;
  436. echo $cfg['_UPLOADSPEED']."\t".': '.number_format($cfg["total_upload"], 2).' kB/s'."\n";
  437. echo $cfg['_DOWNLOADSPEED']."\t".': '.number_format($cfg["total_download"], 2).' kB/s'."\n";
  438. echo $cfg['_TOTALSPEED']."\t".': '.number_format($cfg["total_download"]+$cfg["total_upload"], 2).' kB/s'."\n";
  439. echo $cfg['_ID_CONNECTIONS']."\t".': '.netstatConnectionsSum()."\n";
  440. return true;
  441. }
  442. /**
  443. * Start Transfer
  444. *
  445. * @param $transfer
  446. * @param $options
  447. * @param array $extra
  448. * @return mixed
  449. */
  450. function _transferStart($transfer, $options = '', $extra = array()) {
  451. global $cfg;
  452. // check transfer
  453. if (!transferExists($transfer)) {
  454. $this->_outputError("transfer does not exist.\n");
  455. return false;
  456. }
  457. // check running
  458. if (isTransferRunning($transfer)) {
  459. $this->_outputError("transfer already running.\n");
  460. return false;
  461. }
  462. // parse options
  463. $optionsSet = $this->_parseOptions(
  464. array( 'p' => 1 ), // Only recognized option is 'p'.
  465. $options, $extra
  466. );
  467. if ($optionsSet === false)
  468. return false;
  469. $profile = isset($optionsSet['p']) ? $optionsSet['p'][0] : null;
  470. // set user
  471. $cfg["user"] = getOwner($transfer);
  472. // output
  473. $this->_outputMessage(
  474. "Starting ".$transfer." for user ".$cfg["user"].
  475. (!empty($profile) ? " using profile ".$profile : '').
  476. " ...\n"
  477. );
  478. $ch = ClientHandler::getInstance(getTransferClient($transfer));
  479. // load and apply profile, if specified (just ignore
  480. // it if profiles are disabled, no error)
  481. if ($cfg['transfer_profiles'] >= 1 && !empty($profile)) {
  482. $ch->settingsDefault($transfer);
  483. $settings = GetProfileSettings($profile);
  484. if (empty($settings) || $settings === false) {
  485. $this->_outputError("profilename ".$profile." is no valid profile.\n");
  486. return false;
  487. }
  488. $ch->rate = $settings['rate'];
  489. $ch->drate = $settings['drate'];
  490. $ch->maxuploads = $settings['maxuploads'];
  491. $ch->superseeder = $settings['superseeder'];
  492. $ch->runtime = $settings['runtime'];
  493. $ch->sharekill = $settings['sharekill'];
  494. $ch->minport = $settings['minport'];
  495. $ch->maxport = $settings['maxport'];
  496. $ch->maxcons = $settings['maxcons'];
  497. $ch->rerequest = $settings['rerequest'];
  498. $ch->settingsSave();
  499. }
  500. // force start, don't queue
  501. $ch->start($transfer, false, false);
  502. if ($ch->state == CLIENTHANDLER_STATE_OK) { /* hooray */
  503. $this->_outputMessage("done.\n");
  504. return true;
  505. } else {
  506. $this->_outputError("failed: ".implode("\n", $ch->messages)."\n");
  507. return false;
  508. }
  509. }
  510. /**
  511. * Stop Transfer
  512. *
  513. * @param $transfer
  514. * @return mixed
  515. */
  516. function _transferStop($transfer) {
  517. global $cfg;
  518. // check transfer
  519. if (!transferExists($transfer)) {
  520. $this->_outputError("transfer does not exist.\n");
  521. return false;
  522. }
  523. // check running
  524. if (!isTransferRunning($transfer)) {
  525. $this->_outputError("transfer not running.\n");
  526. return false;
  527. }
  528. // set user
  529. $cfg["user"] = getOwner($transfer);
  530. // output
  531. $this->_outputMessage("Stopping ".$transfer." for user ".$cfg["user"]."...\n");
  532. // stop
  533. $ch = ClientHandler::getInstance(getTransferClient($transfer));
  534. $ch->stop($transfer);
  535. $this->_outputMessage("done.\n");
  536. return true;
  537. }
  538. /**
  539. * Enqueue Transfer
  540. *
  541. * @param $transfer
  542. * @return mixed
  543. */
  544. function _transferEnqueue($transfer) {
  545. global $cfg;
  546. // initialize service-mod (why here ? see "fluxd-single-thread-problem")
  547. FluxdServiceMod::initializeServiceMod('Qmgr');
  548. // check queue
  549. if (!FluxdQmgr::isRunning()) {
  550. $this->_outputError("Qmgr is not running.\n");
  551. return false;
  552. }
  553. // check transfer
  554. if (!transferExists($transfer)) {
  555. $this->_outputError("transfer does not exist.\n");
  556. return false;
  557. }
  558. // check running
  559. if (isTransferRunning($transfer)) {
  560. $this->_outputError("transfer already running.\n");
  561. return false;
  562. }
  563. // set user
  564. $cfg["user"] = getOwner($transfer);
  565. // output
  566. $this->_outputMessage("Enqueue ".$transfer." for user ".$cfg["user"]."...\n");
  567. // force start, don't queue
  568. $ch = ClientHandler::getInstance(getTransferClient($transfer));
  569. $ch->start($transfer, false, true);
  570. if ($ch->state == CLIENTHANDLER_STATE_OK) { /* hooray */
  571. $this->_outputMessage("done.\n");
  572. return true;
  573. } else {
  574. $this->_outputError("failed: ".implode("\n", $ch->messages)."\n");
  575. return false;
  576. }
  577. }
  578. /**
  579. * Dequeue Transfer
  580. *
  581. * @param $transfer
  582. * @return mixed
  583. */
  584. function _transferDequeue($transfer) {
  585. global $cfg;
  586. // initialize service-mod (why here ? see "fluxd-single-thread-problem")
  587. FluxdServiceMod::initializeServiceMod('Qmgr');
  588. // check queue
  589. if (!FluxdQmgr::isRunning()) {
  590. $this->_outputError("Qmgr is not running.\n");
  591. return false;
  592. }
  593. // check transfer
  594. if (!transferExists($transfer)) {
  595. $this->_outputError("transfer does not exist.\n");
  596. return false;
  597. }
  598. // set user
  599. $cfg["user"] = getOwner($transfer);
  600. // output
  601. $this->_outputMessage("Dequeue ".$transfer." for user ".$cfg["user"]."...\n");
  602. // dequeue
  603. FluxdQmgr::dequeueTransfer($transfer, $cfg["user"]);
  604. $this->_outputMessage("done.\n");
  605. return true;
  606. }
  607. /**
  608. * Reset Transfer
  609. *
  610. * @param $transfer
  611. * @return mixed
  612. */
  613. function _transferReset($transfer) {
  614. $this->_outputMessage("Resetting totals of ".$transfer." ...\n");
  615. $msgs = resetTransferTotals($transfer, false);
  616. if (count($msgs) == 0) {
  617. $this->_outputMessage("done.\n");
  618. return true;
  619. } else {
  620. $this->_outputError("failed: ".implode("\n", $msgs)."\n");
  621. return false;
  622. }
  623. }
  624. /**
  625. * Delete Transfer
  626. *
  627. * @param $transfer
  628. * @return mixed
  629. */
  630. function _transferDelete($transfer) {
  631. global $cfg;
  632. // check transfer
  633. if (!transferExists($transfer)) {
  634. $this->_outputError("transfer does not exist.\n");
  635. return false;
  636. }
  637. $this->_outputMessage("Delete ".$transfer." ...\n");
  638. // set user
  639. $cfg["user"] = getOwner($transfer);
  640. // delete
  641. $ch = ClientHandler::getInstance(getTransferClient($transfer));
  642. $tRunningFlag = isTransferRunning($transfer);
  643. if ($tRunningFlag) {
  644. // stop transfer first
  645. $this->_outputMessage("transfer is running, stopping first...\n");
  646. $ch->stop($transfer);
  647. $tRunningFlag = isTransferRunning($transfer);
  648. }
  649. if (!$tRunningFlag) {
  650. $this->_outputMessage("Deleting...\n");
  651. $ch->delete($transfer);
  652. $this->_outputMessage("done.\n");
  653. return true;
  654. } else {
  655. $this->_outputError("transfer still up... cannot delete\n");
  656. return false;
  657. }
  658. }
  659. /**
  660. * Wipe Transfer
  661. *
  662. * @param $transfer
  663. * @return mixed
  664. */
  665. function _transferWipe($transfer) {
  666. global $cfg;
  667. // check transfer
  668. if (!transferExists($transfer)) {
  669. $this->_outputError("transfer does not exist.\n");
  670. return false;
  671. }
  672. $this->_outputMessage("Wipe ".$transfer." ...\n");
  673. // set user
  674. $cfg["user"] = getOwner($transfer);
  675. // wipe
  676. $ch = ClientHandler::getInstance(getTransferClient($transfer));
  677. $tRunningFlag = isTransferRunning($transfer);
  678. if ($tRunningFlag) {
  679. // stop transfer first
  680. $this->_outputMessage("transfer is running, stopping first...\n");
  681. $ch->stop($transfer);
  682. $tRunningFlag = isTransferRunning($transfer);
  683. }
  684. if (!$tRunningFlag) {
  685. $this->_outputMessage("Deleting...\n");
  686. $msgsDelete = deleteTransferData($transfer);
  687. $countDelete = count($msgsDelete);
  688. $msgsReset = resetTransferTotals($transfer, true);
  689. $countReset = count($msgsReset);
  690. if (($countDelete + $countReset) == 0) {
  691. $this->_outputMessage("done.\n");
  692. return true;
  693. } else {
  694. $this->_outputError("there were problems: "
  695. .(($countDelete > 0) ? implode("\n", $msgsDelete)."\n" : "")
  696. .(($countReset > 0) ? implode("\n", $msgsReset) : "")
  697. ."\n"
  698. );
  699. return false;
  700. }
  701. } else {
  702. $this->_outputError("transfer still up... cannot delete\n");
  703. return false;
  704. }
  705. }
  706. /**
  707. * Start Transfers
  708. *
  709. * @param $options
  710. * @param array $extra
  711. * @return mixed
  712. */
  713. function _transfersStart($options = '', $extra = array()) {
  714. // parse options
  715. $optionsSet = $this->_parseOptions(
  716. array( 'p' => 1 ), // Only recognized option is 'p'.
  717. $options, $extra
  718. );
  719. if ($optionsSet === false)
  720. return false;
  721. $profile = isset($optionsSet['p']) ? $optionsSet['p'][0] : null;
  722. $this->_outputMessage(
  723. "Starting all transfers".
  724. (!empty($profile) ? " using profile ".$profile : '').
  725. " ...\n"
  726. );
  727. // build args for _transferStart
  728. $newOptions = $this->_buildOptions('p', $optionsSet); // Pass-thru option 'p'.
  729. $transferList = getTransferArray();
  730. foreach ($transferList as $transfer) {
  731. if (!isTransferRunning($transfer))
  732. $this->_transferStart($transfer, $newOptions[0], $newOptions[1]);
  733. }
  734. }
  735. /**
  736. * Resume Transfers
  737. *
  738. * @param $options
  739. * @param array $extra
  740. * @return mixed
  741. */
  742. function _transfersResume($options = '', $extra = array()) {
  743. // parse options
  744. $optionsSet = $this->_parseOptions(
  745. array( 'p' => 1 ), // Only recognized option is 'p'.
  746. $options, $extra
  747. );
  748. if ($optionsSet === false)
  749. return false;
  750. $profile = isset($optionsSet['p']) ? $optionsSet['p'][0] : null;
  751. $this->_outputMessage(
  752. "Resuming all transfers".
  753. (!empty($profile) ? " using profile ".$profile : '').
  754. " ...\n"
  755. );
  756. // build args for _transferStart
  757. $newOptions = $this->_buildOptions('p', $optionsSet); // Pass-thru option 'p'.
  758. $transferList = getTransferArray();
  759. $sf = new StatFile("");
  760. foreach ($transferList as $transfer) {
  761. $sf->init($transfer);
  762. if (trim($sf->running) == 0)
  763. $this->_transferStart($transfer, $newOptions[0], $newOptions[1]);
  764. }
  765. }
  766. /**
  767. * Stop Transfers
  768. *
  769. * @return mixed
  770. */
  771. function _transfersStop() {
  772. $this->_outputMessage("Stopping all transfers ...\n");
  773. $transferList = getTransferArray();
  774. foreach ($transferList as $transfer) {
  775. if (isTransferRunning($transfer))
  776. $this->_transferStop($transfer);
  777. }
  778. }
  779. /**
  780. * set transfer setting
  781. *
  782. * @param $transfer
  783. * @param $key
  784. * @param $val
  785. * @param $options
  786. * @return mixed
  787. */
  788. function _tset($transfer, $key, $val, $options) {
  789. global $cfg;
  790. // check transfer
  791. if (!transferExists($transfer)) {
  792. $this->_outputError("transfer does not exist.\n");
  793. return false;
  794. }
  795. // check params
  796. $settingsKeys = array(
  797. 'uprate' => 'NUMBER',
  798. 'downrate' => 'NUMBER',
  799. 'completion' => 'BOOL',
  800. 'sharekill' => 'NUMBER'
  801. );
  802. if (!array_key_exists($key, $settingsKeys)) {
  803. $this->_outputError("invalid settings-key: ".$key."\n");
  804. return false;
  805. }
  806. if (strlen($val) < 1) {
  807. $this->_outputError("value for ".$key." invalid.\n");
  808. return false;
  809. }
  810. switch ($settingsKeys[$key]) {
  811. case 'NUMBER':
  812. if (!preg_match('/^[0-9\-]+$/D', $val)) {
  813. $this->_outputError("value for ".$key." must be a number: ".$val."\n");
  814. return false;
  815. }
  816. break;
  817. case 'BOOL':
  818. $val = strtolower($val);
  819. if (($val != 'true') && ($val != 'false')) {
  820. $this->_outputError("value for ".$key." must be true or false: ".$val."\n");
  821. return false;
  822. }
  823. break;
  824. }
  825. // set user
  826. $cfg["user"] = getOwner($transfer);
  827. // output
  828. $this->_outputMessage("Setting ".$key." to ".$val." for ".$transfer." for user ".$cfg["user"]."...\n");
  829. // init ch-instance
  830. $ch = ClientHandler::getInstance(getTransferClient($transfer));
  831. // load settings, default if settings could not be loaded (fresh transfer)
  832. if ($ch->settingsLoad($transfer) !== true)
  833. $ch->settingsDefault();
  834. // autosend
  835. $send = ((strpos($options, 's') !== false) && (isTransferRunning($transfer)));
  836. // set setting
  837. switch ($key) {
  838. case 'uprate':
  839. if ($ch->rate != $val) {
  840. $ch->setRateUpload($transfer, $val, $send);
  841. break;
  842. } else {
  843. $this->_outputMessage("no changes.\n");
  844. return false;
  845. }
  846. case 'downrate':
  847. if ($ch->drate != $val) {
  848. $ch->setRateDownload($transfer, $val, $send);
  849. break;
  850. } else {
  851. $this->_outputMessage("no changes.\n");
  852. return false;
  853. }
  854. case 'completion':
  855. if (strtolower($ch->runtime) != $val) {
  856. $ch->setRuntime($transfer, ($val == 'true') ? 'True' : 'False', $send);
  857. break;
  858. } else {
  859. $this->_outputMessage("no changes.\n");
  860. return false;
  861. }
  862. case 'sharekill':
  863. if ($ch->sharekill != $val) {
  864. $ch->setSharekill($transfer, $val, $send);
  865. break;
  866. } else {
  867. $this->_outputMessage("no changes.\n");
  868. return false;
  869. }
  870. }
  871. // save
  872. $ch->settingsSave();
  873. // output + return
  874. if ($send)
  875. $this->_outputMessage("settings saved + changes sent to client.\n");
  876. else
  877. $this->_outputMessage("settings saved.\n");
  878. return true;
  879. }
  880. /**
  881. * Inject Transfer
  882. *
  883. * @param $transferFile
  884. * @param $username
  885. * @param $options
  886. * @param array $extra
  887. * @return mixed
  888. */
  889. function _inject($transferFile, $username, $options = '', $extra = array()) {
  890. global $cfg;
  891. // check file
  892. if (!@is_file($transferFile)) {
  893. $this->_outputError("transfer-file ".$transferFile." is no file.\n");
  894. return false;
  895. }
  896. // check username
  897. if (!IsUser($username)) {
  898. $this->_outputError("username ".$username." is no valid user.\n");
  899. return false;
  900. }
  901. // parse options
  902. $optionsSet = $this->_parseOptions(
  903. array( 'd' => 0, 's' => 0, 'p' => 1 ), // Recognized options are 'd', 's' and 'p'.
  904. $options, $extra
  905. );
  906. if ($optionsSet === false)
  907. return false;
  908. $profile = isset($optionsSet['p']) ? $optionsSet['p'][0] : null;
  909. $this->_outputMessage(
  910. "Inject ".$transferFile." for user ".$username.
  911. (!empty($profile) ? " using profile ".$profile : '').
  912. " ...\n"
  913. );
  914. // set user
  915. $cfg["user"] = $username;
  916. // set filename
  917. $transfer = basename($transferFile);
  918. $transfer = tfb_cleanFileName($transfer);
  919. // only inject valid transfers
  920. $msgs = array();
  921. if ($transfer !== false) {
  922. $targetFile = $cfg["transfer_file_path"].$transfer;
  923. if (@is_file($targetFile)) {
  924. array_push($msgs, "transfer ".$transfer.", already exists.");
  925. } else {
  926. $this->_outputMessage("copy ".$transferFile." to ".$targetFile." ...\n");
  927. if (@copy($transferFile, $targetFile)) {
  928. // chmod
  929. @chmod($cfg["transfer_file_path"].$transfer, 0644);
  930. // make owner entry
  931. AuditAction($cfg["constants"]["file_upload"], $transfer);
  932. // inject
  933. $this->_outputMessage("injecting ".$transfer." ...\n");
  934. injectTransfer($transfer);
  935. // delete source-file
  936. if (isset($optionsSet['d'])) {
  937. $this->_outputMessage("deleting source-file ".$transferFile." ...\n");
  938. @unlink($transferFile);
  939. }
  940. // start
  941. if (isset($optionsSet['s'])) {
  942. // build args for _transferStart
  943. $newOptions = $this->_buildOptions('p', $optionsSet); // Pass-thru option 'p'.
  944. return $this->_transferStart($transfer, $newOptions[0], $newOptions[1]);
  945. }
  946. // return
  947. else
  948. return true;
  949. } else {
  950. array_push($msgs, "File could not be copied: ".$transferFile);
  951. }
  952. }
  953. } else {
  954. array_push($msgs, "The type of file you are injecting is not allowed.");
  955. array_push($msgs, "valid file-extensions: ");
  956. array_push($msgs, $cfg["file_types_label"]);
  957. }
  958. if (count($msgs) == 0) {
  959. $this->_outputMessage("done.\n");
  960. return true;
  961. } else {
  962. $this->_outputError("failed: ".implode("\n", $msgs)."\n");
  963. return false;
  964. }
  965. }
  966. /**
  967. * Watch Dir
  968. *
  969. * @param $watchDir
  970. * @param $username
  971. * @param $options
  972. * @param array $extra
  973. * @return mixed
  974. */
  975. function _watch($watchDir, $username, $options = '', $extra = array()) {
  976. global $cfg;
  977. // check dir
  978. if (!@is_dir($watchDir)) {
  979. $this->_outputError("watch-dir ".$watchDir." is no dir.\n");
  980. return false;
  981. }
  982. // check username
  983. if (!IsUser($username)) {
  984. $this->_outputError("username ".$username." is no valid user.\n");
  985. return false;
  986. }
  987. // parse options
  988. $optionsSet = $this->_parseOptions(
  989. array( 'd' => 0, 's' => 0, 'p' => 1 ), // Recognized options are 'd', 's' and 'p'.
  990. $options, $extra
  991. );
  992. if ($optionsSet === false)
  993. return false;
  994. $profile = isset($optionsSet['p']) ? $optionsSet['p'][0] : null;
  995. $this->_outputMessage(
  996. "Processing watch-dir ".$watchDir." for user ".$username.
  997. (!empty($profile) ? " using profile ".$profile : '').
  998. " ...\n"
  999. );
  1000. // process dir
  1001. if ($dirHandle = @opendir($watchDir)) {
  1002. // get input-files
  1003. $input = array();
  1004. while (false !== ($file = @readdir($dirHandle)))
  1005. if (@is_file($watchDir.$file))
  1006. array_push($input, $file);
  1007. @closedir($dirHandle);
  1008. if (empty($input)) {
  1009. $this->_outputMessage("done. no files found.\n");
  1010. return true;
  1011. }
  1012. // trailing slash
  1013. $watchDir = checkDirPathString($watchDir);
  1014. // build args for _inject
  1015. $newOptions = $this->_buildOptions('dsp', $optionsSet); // Pass-thru options 'd', 's' and 'p'.
  1016. // process input-files
  1017. $ctr = array('files' => count($input), 'ok' => 0);
  1018. foreach ($input as $transfer) {
  1019. // inject, increment if ok
  1020. if ($this->_inject($watchDir.$transfer, $username, $newOptions[0], $newOptions[1]) !== false)
  1021. $ctr['ok']++;
  1022. }
  1023. if ($ctr['files'] == $ctr['ok']) {
  1024. $this->_outputMessage("done. files: ".$ctr['files']."; ok: ".$ctr['ok']."\n");
  1025. return true;
  1026. } else {
  1027. $this->_outputError("done with errors. files: ".$ctr['files']."; ok: ".$ctr['ok']."\n");
  1028. return false;
  1029. }
  1030. } else {
  1031. $this->_outputError("failed to open watch-dir ".$watchDir.".\n");
  1032. return false;
  1033. }
  1034. }
  1035. /**
  1036. * Xfer Shutdown
  1037. *
  1038. * @param $delta
  1039. * @return mixed
  1040. */
  1041. function _xfer($delta) {
  1042. global $cfg, $db;
  1043. // check xfer
  1044. if ($cfg['enable_xfer'] != 1) {
  1045. $this->_outputError("xfer must be enabled.\n");
  1046. return false;
  1047. }
  1048. // check arg
  1049. if (($delta != "all") && ($delta != "total") && ($delta != "month") && ($delta != "week") && ($delta != "day")) {
  1050. $this->_outputMessage('invalid delta : "'.$delta.'"'."\n");
  1051. return false;
  1052. }
  1053. $this->_outputMessage('checking xfer-limit(s) for "'.$delta.'" ...'."\n");
  1054. // set xfer-realtime
  1055. $cfg['xfer_realtime'] = 1;
  1056. // set xfer-newday
  1057. Xfer::setNewday();
  1058. // getTransferListArray to update xfer-stats
  1059. $transferList = @getTransferListArray();
  1060. // get xfer-totals
  1061. $xfer_total = Xfer::getStatsTotal();
  1062. // check if break needed
  1063. // total
  1064. if (($delta == "total") || ($delta == "all")) {
  1065. // only do if a limit is set
  1066. if ($cfg["xfer_total"] > 0) {
  1067. if ($xfer_total['total']['total'] >= $cfg["xfer_total"] * 1048576) {
  1068. // limit met, stop all Transfers now.
  1069. $this->_outputMessage('Limit met for "total" : '.formatFreeSpace($xfer_total['total']['total'] / (1048576))." / ".formatFreeSpace($cfg["xfer_total"])."\n");
  1070. return $this->_transfersStop();
  1071. } else {
  1072. $this->_outputMessage('Limit not met for "total" : '.formatFreeSpace($xfer_total['total']['total'] / (1048576))." / ".formatFreeSpace($cfg["xfer_total"])."\n");
  1073. }
  1074. } else {
  1075. $this->_outputMessage('no limit set for "total"'."\n");
  1076. }
  1077. }
  1078. // month
  1079. if (($delta == "month") || ($delta == "all")) {
  1080. // only do if a limit is set
  1081. if ($cfg["xfer_month"] > 0) {
  1082. if ($xfer_total['month']['total'] >= $cfg["xfer_month"] * 1048576) {
  1083. // limit met, stop all Transfers now.
  1084. $this->_outputMessage('Limit met for "month" : '.formatFreeSpace($xfer_total['month']['total'] / (1048576))." / ".formatFreeSpace($cfg["xfer_month"])."\n");
  1085. return $this->_transfersStop();
  1086. } else {
  1087. $this->_outputMessage('Limit not met for "month" : '.formatFreeSpace($xfer_total['month']['total'] / (1048576))." / ".formatFreeSpace($cfg["xfer_month"])."\n");
  1088. }
  1089. } else {
  1090. $this->_outputMessage('no limit set for "month"'."\n");
  1091. }
  1092. }
  1093. // week
  1094. if (($delta == "week") || ($delta == "all")) {
  1095. // only do if a limit is set
  1096. if ($cfg["xfer_week"] > 0) {
  1097. if ($xfer_total['week']['total'] >= $cfg["xfer_week"] * 1048576) {
  1098. // limit met, stop all Transfers now.
  1099. $this->_outputMessage('Limit met for "week" : '.formatFreeSpace($xfer_total['week']['total'] / (1048576))." / ".formatFreeSpace($cfg["xfer_week"])."\n");
  1100. return $this->_transfersStop();
  1101. } else {
  1102. $this->_outputMessage('Limit not met for "week" : '.formatFreeSpace($xfer_total['week']['total'] / (1048576))." / ".formatFreeSpace($cfg["xfer_week"])."\n");
  1103. }
  1104. } else {
  1105. $this->_outputMessage('no limit set for "week"'."\n");
  1106. }
  1107. }
  1108. // day
  1109. if (($delta == "day") || ($delta == "all")) {
  1110. // only do if a limit is set
  1111. if ($cfg["xfer_day"] > 0) {
  1112. if ($xfer_total['day']['total'] >= $cfg["xfer_day"] * 1048576) {
  1113. // limit met, stop all Transfers now.
  1114. $this->_outputMessage('Limit met for "day" : '.formatFreeSpace($xfer_total['day']['total'] / (1048576))." / ".formatFreeSpace($cfg["xfer_day"])."\n");
  1115. return $this->_transfersStop();
  1116. } else {
  1117. $this->_outputMessage('Limit not met for "day" : '.formatFreeSpace($xfer_total['day']['total'] / (1048576))." / ".formatFreeSpace($cfg["xfer_day"])."\n");
  1118. }
  1119. } else {
  1120. $this->_outputMessage('no limit set for "day"'."\n");
  1121. }
  1122. }
  1123. // done
  1124. $this->_outputMessage("done.\n");
  1125. return true;
  1126. }
  1127. /**
  1128. * rss download
  1129. *
  1130. * @param $saveDir
  1131. * @param $filterFile
  1132. * @param $historyFile
  1133. * @param $url
  1134. * @param $username
  1135. * @return mixed
  1136. */
  1137. function _rss($saveDir, $filterFile, $historyFile, $url, $username = "") {
  1138. global $cfg;
  1139. // set user
  1140. if (!empty($username)) {
  1141. // check first
  1142. if (IsUser($username)) {
  1143. $cfg["user"] = $username;
  1144. } else {
  1145. $this->_outputError("username ".$username." is no valid user.\n");
  1146. return false;
  1147. }
  1148. }
  1149. // process Feed
  1150. require_once("inc/classes/Rssd.php");
  1151. return Rssd::processFeed($saveDir, $filterFile, $historyFile, $url);
  1152. }
  1153. /**
  1154. * Repair
  1155. *
  1156. * @return mixed
  1157. */
  1158. function _repair() {
  1159. require_once("inc/classes/MaintenanceAndRepair.php");
  1160. MaintenanceAndRepair::repair();
  1161. return true;
  1162. }
  1163. /**
  1164. * Maintenance
  1165. *
  1166. * @param $trestart
  1167. * @return mixed
  1168. */
  1169. function _maintenance($trestart) {
  1170. // initialize service-mod (why here ? see "fluxd-single-thread-problem")
  1171. FluxdServiceMod::initializeServiceMod('Qmgr');
  1172. require_once("inc/classes/MaintenanceAndRepair.php");
  1173. MaintenanceAndRepair::maintenance(
  1174. $trestart ? MAINTENANCEANDREPAIR_TYPE_EXT : MAINTENANCEANDREPAIR_TYPE_STD);
  1175. return true;
  1176. }
  1177. /**
  1178. * Dump Database
  1179. *
  1180. * @param $type
  1181. * @return mixed
  1182. */
  1183. function _dump($type) {
  1184. global $cfg, $db;
  1185. switch ($type) {
  1186. case "settings":
  1187. $sql = "SELECT tf_key, tf_value FROM tf_settings";
  1188. break;
  1189. case "users":
  1190. $sql = "SELECT uid, user_id FROM tf_users";
  1191. break;
  1192. default:
  1193. $this->_outputError("invalid type : ".$type."\n");
  1194. return false;
  1195. }
  1196. $recordset = $db->Execute($sql);
  1197. if ($db->ErrorNo() != 0) dbError($sql);
  1198. $content = "";
  1199. while (list($a, $b) = $recordset->FetchRow())
  1200. $content .= $a._DUMP_DELIM.$b."\n";
  1201. echo $content;
  1202. return ($content != "");
  1203. }
  1204. /**
  1205. * output message
  1206. *
  1207. * @param $message
  1208. */
  1209. function _outputMessage($message) {
  1210. printMessage($this->name, $message);
  1211. }
  1212. /**
  1213. * output error
  1214. *
  1215. * @param $message
  1216. */
  1217. function _outputError($message) {
  1218. printError($this->name, $message);
  1219. }
  1220. /**
  1221. * prints version
  1222. *
  1223. * @return mixed
  1224. */
  1225. function _printVersion() {
  1226. echo $this->name." Revision "._REVISION_FLUXCLI."\n";
  1227. return (_REVISION_FLUXCLI > 0);
  1228. }
  1229. /**
  1230. * prints usage
  1231. *
  1232. * @return mixed
  1233. */
  1234. function _printUsage() {
  1235. $this->_printVersion();
  1236. echo "\n"
  1237. . "Usage: ".$this->_script." action [extra-args]\n"
  1238. . "\n"
  1239. . "action: \n"
  1240. . " transfers : show transfers.\n"
  1241. . " netstat : show netstat.\n"
  1242. . " start : start a transfer.\n"
  1243. . " extra-arg 1 : name of transfer as known inside webapp\n"
  1244. . " extra-arg 2 : options (p) (optional, default: none)\n"
  1245. . " options-arg contains 'p' : use transfer-profile\n"
  1246. . " extra-arg 3 : transfer-profile name (optional, default: none)\n"
  1247. . " stop : stop a transfer.\n"
  1248. . " extra-arg : name of transfer as known inside webapp\n"
  1249. . " reset : reset totals of a transfer.\n"
  1250. . " extra-arg : name of transfer as known inside webapp\n"
  1251. . " delete : delete a transfer.\n"
  1252. . " extra-arg : name of transfer as known inside webapp\n"
  1253. . " wipe : reset totals, delete metafile, delete data.\n"
  1254. . " extra-arg : name of transfer as known inside webapp\n"
  1255. . " enqueue : enqueue a transfer.\n"
  1256. . " extra-arg : name of transfer as known inside webapp\n"
  1257. . " dequeue : dequeue a transfer.\n"
  1258. . " extra-arg : name of transfer as known inside webapp\n"
  1259. . " start-all : start all transfers.\n"
  1260. . " extra-arg 1 : options (p) (optional, default: none)\n"
  1261. . " options-arg contains 'p' : use transfer-profile\n"
  1262. . " extra-arg 2 : transfer-profile name (optional, default: none)\n"
  1263. . " resume-all : resume all transfers.\n"
  1264. . " extra-arg 1 : options (p) (optional, default: none)\n"
  1265. . " options-arg contains 'p' : use transfer-profile\n"
  1266. . " extra-arg 2 : transfer-profile name (optional, default: none)\n"
  1267. . " stop-all : stop all running transfers.\n"
  1268. . " tset : set a transfer-setting.\n"
  1269. . " extra-arg 1 : name of transfer as known inside webapp\n"
  1270. . " extra-arg 2 : settings-key\n"
  1271. . " extra-arg 3 : settings-value\n"
  1272. . " extra-arg 4 : options (optional, default: s)\n"
  1273. . " options-arg contains 's' : send changes to running client\n"
  1274. . " valid settings :\n"
  1275. . " uprate ; value: uprate in kB/s ; options: s\n"
  1276. . " downrate ; value: downrate in kB/s ; options: s\n"
  1277. . " completion ; value: true/false ; options: s\n"
  1278. . " sharekill ; value: seed-percentage ; options: s\n"
  1279. . " inject : injects (+ starts) a transfer.\n"
  1280. . " extra-arg 1 : path to transfer-meta-file\n"
  1281. . " extra-arg 2 : username of fluxuser\n"
  1282. . " extra-arg 3 : options (d/s/p) (optional, default: none)\n"
  1283. . " options-arg contains 'd' : delete source-file after inject\n"
  1284. . " options-arg contains 's' : start transfer after inject\n"
  1285. . " options-arg contains 'p' : use transfer-profile\n"
  1286. . " extra-arg 4 : transfer-profile name (optional, default: none)\n"
  1287. . " watch : watch a dir and inject (+ start) transfers.\n"
  1288. . " extra-arg 1 : watch-dir\n"
  1289. . " extra-arg 2 : username of fluxuser\n"
  1290. . " extra-arg 3 : options (d/s/p) (optional, default: ds)\n"
  1291. . " options-arg contains 'd' : delete source-file(s) after inject\n"
  1292. . " options-arg contains 's' : start transfer(s) after inject\n"
  1293. . " options-arg contains 'p' : use transfer-profile\n"
  1294. . " extra-arg 4 : transfer-profile name (optional, default: none)\n"
  1295. . " rss : download torrents matching filter-rules from a rss-feed.\n"
  1296. . " extra-arg 1 : save-dir\n"
  1297. . " extra-arg 2 : filter-file\n"
  1298. . " extra-arg 3 : history-file\n"
  1299. . " extra-arg 4 : rss-feed-url\n"
  1300. . " extra-arg 5 : use cookies from this torrentflux user (optional, default: superadmin)\n"
  1301. . " xfer : xfer-Limit-Shutdown. stop all transfers if xfer-limit is met.\n"
  1302. . " extra-arg 1 : time-delta of xfer to use : (all/total/month/week/day)\n"
  1303. . " repair : repair of torrentflux. DON'T do this unless you have to.\n"
  1304. . " Doing this on a running ok flux _will_ screw up things.\n"
  1305. . " maintenance : call maintenance and repair all died transfers.\n"
  1306. . " extra-arg 1 : restart died transfers (true/false. optional, default: false)\n"
  1307. . " dump : dump database.\n"
  1308. . " extra-arg 1 : type. (settings/users)\n"
  1309. . " filelist : print file-list.\n"
  1310. . " extra-arg 1 : dir (optional, default: docroot)\n"
  1311. . " checksums : print checksum-list.\n"
  1312. . " extra-arg 1 : dir (optional, default: docroot)\n"
  1313. . "\n"
  1314. . "examples:\n"
  1315. . $this->_script." transfers\n"
  1316. . $this->_script." netstat\n"
  1317. . $this->_script." start foo.torrent\n"
  1318. . $this->_script." start foo.torrent p profilename\n"
  1319. . $this->_script." stop foo.torrent\n"
  1320. . $this->_script." enqueue foo.torrent\n"
  1321. . $this->_script." dequeue foo.torrent\n"
  1322. . $this->_script." start-all\n"
  1323. . $this->_script." start-all p profilename\n"
  1324. . $this->_script." resume-all\n"
  1325. . $this->_script." stop-all\n"
  1326. . $this->_script." tset foo.torrent uprate 100\n"
  1327. . $this->_script." tset foo.torrent downrate 100\n"
  1328. . $this->_script." tset foo.torrent completion false\n"
  1329. . $this->_script." tset foo.torrent sharekill 200\n"
  1330. . $this->_script." reset foo.torrent\n"
  1331. . $this->_script." delete foo.torrent\n"
  1332. . $this->_script." wipe foo.torrent\n"
  1333. . $this->_script." inject /path/to/foo.torrent fluxuser\n"
  1334. . $this->_script." inject /path/to/foo.torrent fluxuser ds\n"
  1335. . $this->_script." inject /path/to/foo.torrent fluxuser sp profilename\n"
  1336. . $this->_script." watch /path/to/watch-dir/ fluxuser\n"
  1337. . $this->_script." watch /path/to/watch-dir/ fluxuser d\n"
  1338. . $this->_script." watch /path/to/watch-dir/ fluxuser dsp profilename\n"
  1339. . $this->_script." rss /path/to/rss-torrents/ /path/to/filter.dat /path/to/filter.hist http://www.example.com/rss.xml\n"
  1340. . $this->_script." rss /path/to/rss-torrents/ /path/to/filter.dat /path/to/filter.hist http://www.example.com/rss.xml fluxuser\n"
  1341. . $this->_script." xfer month\n"
  1342. . $this->_script." repair\n"
  1343. . $this->_script." maintenance true\n"
  1344. . $this->_script." dump settings\n"
  1345. . $this->_script." dump users\n"
  1346. . $this->_script." filelist /var/www\n"
  1347. . $this->_script." checksums /var/www\n"
  1348. . "\n";
  1349. if (count($this->_argErrors) > 0) {
  1350. echo "arg-error(s) :\n"
  1351. . implode("\n", $this->_argErrors)
  1352. . "\n\n";
  1353. return false;
  1354. }
  1355. return true;
  1356. }
  1357. }
  1358. ?>