/** * starts a client * * @param $transfer name of the transfer * @param $interactive (boolean) : is this a interactive startup with dialog ? * @param $enqueue (boolean) : enqueue ? */ function start($transfer, $interactive = false, $enqueue = false) { global $cfg; // set vars $this->_setVarsForTransfer($transfer); // log $this->logMessage($this->client . "-start : " . $transfer . "\n", true); // FluAzu require_once "inc/classes/FluAzu.php"; // do azureus special-pre-start-checks // check to see if fluazu is running if (!FluAzu::isRunning()) { $this->state = CLIENTHANDLER_STATE_ERROR; $msg = "fluazu not running, cannot start transfer " . $transfer; AuditAction($cfg["constants"]["error"], $msg); $this->logMessage($msg . "\n", true); array_push($this->messages, $msg); // write error to stat $sf = new StatFile($this->transfer, $this->owner); $sf->time_left = 'Error: fluazu down'; $sf->write(); // return return false; } // init starting of client $this->_init($interactive, $enqueue, true, false); // only continue if init succeeded (skip start / error) if ($this->state != CLIENTHANDLER_STATE_READY) { if ($this->state == CLIENTHANDLER_STATE_ERROR) { $msg = "Error after init (" . $transfer . "," . $interactive . "," . $enqueue . ",true," . $cfg['enable_sharekill'] . ")"; array_push($this->messages, $msg); $this->logMessage($msg . "\n", true); } // return return false; } // build the command-string $content = $cfg['user'] . "\n"; $content .= $this->savepath . "\n"; $content .= $this->rate . "\n"; $content .= $this->drate . "\n"; $content .= $this->maxuploads . "\n"; $content .= $this->superseeder . "\n"; $content .= $this->runtime . "\n"; $content .= $this->sharekill_param . "\n"; $content .= $this->minport . "\n"; $content .= $this->maxport . "\n"; $content .= $this->maxcons . "\n"; $content .= $this->rerequest; $this->command = "echo -e " . tfb_shellencode($content) . " > " . tfb_shellencode($cfg["path"] . '.fluazu/run/' . $transfer); $this->command .= " && "; $this->command .= "echo r > " . tfb_shellencode($cfg["path"] . '.fluazu/fluazu.cmd'); // start the client $this->_start(); }
/** * transfers * * @param $action */ function sa_transfers($action = "") { global $cfg, $error, $statusImage, $statusMessage, $htmlTitle, $htmlTop, $htmlMain; if ($action == "") { return; } buildPage("t"); switch ($action) { case "0": // Transfers-main $htmlTitle = "Transfer Bulk Operations"; $htmlMain .= '<br><div align="left">'; $htmlMain .= '<p>Select action to perform on all items in the transfer list:</p>'; $htmlMain .= '<a href="' . _FILE_THIS . '?t=1"><img src="themes/' . $cfg["theme"] . '/images/arrow.gif" width="9" height="9" title="Stop All Transfers" border="0"> Stop All Transfers</a>'; $htmlMain .= '<p>'; $htmlMain .= '<a href="' . _FILE_THIS . '?t=2"><img src="themes/' . $cfg["theme"] . '/images/arrow.gif" width="9" height="9" title="Start All Transfers" border="0"> Start All Transfers</a>'; $htmlMain .= '<p>'; $htmlMain .= '<a href="' . _FILE_THIS . '?t=3"><img src="themes/' . $cfg["theme"] . '/images/arrow.gif" width="9" height="9" title="Resume All Transfers" border="0"> Resume All Transfers</a>'; $htmlMain .= '<br><br><strong>Note:</strong><br>\'Start All Transfers\' will start all transfers in the transfer list, regardless of whether they have been started previously or not.<br><br>\'Resume All Transfers\' will only start those transfers that have previously been started and are currently in the \'stopped\' state'; $htmlMain .= '</div><br><br>'; break; case "1": // Transfers-Stop $htmlTitle = "Transfers - Stop"; $htmlMain .= '<br><strong>Transfers Stopped:</strong><br>'; $htmlMain .= '<pre>'; $transferList = getTransferArray(); foreach ($transferList as $transfer) { if (isTransferRunning($transfer)) { $ch = ClientHandler::getInstance(getTransferClient($transfer)); $ch->stop($transfer); $htmlMain .= ' - ' . $transfer . ""; $htmlMain .= "\n"; } } $htmlMain .= '</pre>'; $htmlMain .= '<hr><br>'; break; case "2": // Transfers-Start $htmlTitle = "Transfers - Start"; $htmlMain .= '<br><strong>Transfers Started:</strong><br>'; $htmlMain .= '<pre>'; $transferList = getTransferArray(); foreach ($transferList as $transfer) { if (!isTransferRunning($transfer)) { $ch = ClientHandler::getInstance(getTransferClient($transfer)); $ch->start($transfer, false, false); $htmlMain .= ' - ' . $transfer . ""; $htmlMain .= "\n"; } } $htmlMain .= '</pre>'; $htmlMain .= '<hr><br>'; break; case "3": // Transfers-Resume $htmlTitle = "Transfers - Resume"; $htmlMain .= '<br><strong>Transfers Resumed:</strong><br>'; $htmlMain .= '<pre>'; $transferList = getTransferArray(); $sf = new StatFile(""); foreach ($transferList as $transfer) { $sf->init($transfer); if (trim($sf->running) == 0 && !isTransferRunning($transfer)) { $ch = ClientHandler::getInstance(getTransferClient($transfer)); $ch->start($transfer, false, false); $htmlMain .= ' - ' . $transfer . ""; $htmlMain .= "\n"; } } $htmlMain .= '</pre>'; $htmlMain .= '<hr><br>'; break; } $htmlMain .= '<br><strong>Transfers:</strong><br>'; $htmlMain .= '<pre>'; $transferList = getTransferArray(); foreach ($transferList as $transfer) { $htmlMain .= ' - ' . $transfer . ""; if (isTransferRunning($transfer)) { $htmlMain .= " (running)"; } $htmlMain .= "\n"; } $htmlMain .= '</pre>'; printPage(); exit; }
/** * change torrent Owner (download same torrent again from another user) * * @param $transfer, $user * @return none */ function changeOwner($transfer, $user) { global $cfg, $db, $transfers; $oldowner = getOwner($transfer); if ($oldowner != $user) { if (file_exists($cfg["transfer_file_path"] . $transfer . ".stat")) { $sf = new StatFile($transfer, $user); $sf->transferowner = $user; $sf->write(); } $hash = getTransferHash($transfer); $uid = (int) GetUID($user); $sql = "INSERT INTO tf_transfer_totals(tid, uid, uptotal,downtotal) values (" . $db->qstr($hash) . "," . $uid . "," . "0,0" . ")"; $result = $db->Execute($sql); if ($db->ErrorNo() != 0) { dbError($sql); } resetOwner($transfer); } }
/** * _updateStatFile * * @param $transfer */ function _updateStatFile($transfer) { global $transfers; $modded = 0; // create sf object $sf = new StatFile($transfer, getOwner($transfer)); if ($sf->percent_done > 0 && $sf->percent_done < 100) { // has downloaded something at some point, mark it is incomplete $sf->running = "0"; $sf->time_left = "Transfer Stopped"; $modded++; } if ($modded == 0) { if ($sf->percent_done == 0 || $sf->percent_done == "") { // We are going to write a '2' on the front of the stat file so that it will be set back to New Status $sf->running = "2"; $sf->time_left = ""; $modded++; } } if ($modded == 0) { if ($sf->percent_done == 100) { // transfer was done and is now being stopped $sf->running = "0"; $sf->time_left = "Download Succeeded!"; $modded++; } } if ($modded == 0) { // hmmm this stat-file is quite strange... just rewrite it stopped. $sf->running = "0"; $sf->time_left = "Transfer Stopped"; } // Write out the new Stat File $sf->write(); // set transfers-cache cacheTransfersSet(); }
/** * resets totals of a transfer * * @param $transfer name of the transfer * @param $delete boolean if to delete meta-file * @return array */ function resetTransferTotals($transfer, $delete = false) { global $cfg, $db, $transfers; $msgs = array(); $tid = getTransferHash($transfer); $client = getTransferClient($transfer); // delete meta-file if ($delete) { $ch = ClientHandler::getInstance($client); $ch->delete($transfer); if (count($ch->messages) > 0) { $msgs = array_merge($msgs, $ch->messages); } } else { // reset in stat-file $sf = new StatFile($transfer, getOwner($transfer)); $sf->uptotal = 0; $sf->downtotal = 0; $sf->write(); if ($client == "vuzerpc") { require_once "inc/functions/functions.rpc.vuze.php"; vuzeResetUpload($tid); } } // reset in db $uid = (int) getTransferOwnerID($transfer); $sql = "UPDATE tf_transfer_totals SET uptotal=0 WHERE tid = " . $db->qstr($tid) . " AND uid IN (0,{$uid})"; $db->Execute($sql); if ($db->ErrorNo() != 0) { dbError($sql); } // set transfers-cache cacheTransfersSet(); return $msgs; }
function updateStatFiles($bShowMissing = false) { global $cfg, $db, $client; $rpc = Transmission::getInstance($cfg); // check if running and get all session variables in cache if (!$rpc->session_get()) { echo "unable to connect to transmission-daemon\n"; return; } $tfs = $rpc->torrent_get_tf(); if (empty($tfs)) { echo "no loaded torrents\n"; return; } $sql = "SELECT hash, transfer, sharekill FROM tf_transfers WHERE type='torrent' AND client = 'transmissionrpc'"; $hashes = array("''"); foreach ($tfs as $hash => $t) { $hashes[] = "'" . strtolower($hash) . "'"; } $sql .= " AND hash IN (" . implode(',', $hashes) . ")"; $recordset = $db->Execute($sql); $hashes = array(); $sharekills = array(); while (list($hash, $transfer, $sharekill) = $recordset->FetchRow()) { $hash = strtolower($hash); $hashes[$hash] = $transfer; $sharekills[$hash] = $sharekill; } $max_ul = 1024.0 * $cfg['max_upload_rate']; $max_dl = 1024.0 * $cfg['max_download_rate']; //SHAREKILLS Checks $nbUpdate = 0; foreach ($tfs as $hash => $t) { if (!isset($sharekills[$hash])) { continue; } if (($t['status'] == 8 || $t['status'] == 9) && $t['sharing'] > $sharekills[$hash]) { $transfer = $hashes[$hash]; $nbUpdate++; if (stopTransmissionTransferCron($hash)) { AuditAction($cfg["constants"]["debug"], $client . ": stop error {$transfer}."); } else { AuditAction($cfg["constants"]["stop_transfer"], $this->client . "-stat. : sharekill stopped {$transfer}"); // flag the transfer as stopped (in db) stopTransferSettings($transfer); } } } echo " stopped {$nbUpdate} torrents.\n"; $nbUpdate = 0; $missing = array(); foreach ($tfs as $hash => $t) { if (!isset($hashes[$hash])) { if ($bShowMissing) { $missing[$t['rpcid']] = $t['name']; } continue; } $transfer = $hashes[$hash]; //file_put_contents($cfg["path"].'.Transmission/'."updateStatFiles4.log",serialize($t)); $sf = new StatFile($transfer); $sf->running = $t['running']; if (empty($sf->transferowner)) { $uid = getTransferOwnerID($hash); if ($uid > 0) { $sf->transferowner = GetUsername($uid); echo "transfer '{$transfer}' owner fixed to " . $sf->transferowner . " \n"; $sf->write(); } } if ($sf->running) { $sharebase = (int) $sharekills[$hash]; //$sharekill = (int) round(floatval($t['seedRatioLimit']) * 100); if ($sharebase > 0 && (int) $sf->seedlimit == 0) { AuditAction($cfg["constants"]["debug"], $client . ": changed empty .stat sharekill " . $sf->seedlimit . " to {$sharebase} (from db), {$transfer}."); $sf->seedlimit = $sharebase; } $max_ul = max($t['urate'], $max_ul); $max_dl = max($t['drate'], $max_dl); $max_share = max($sharebase, $sharekill); if ($t['eta'] > 0 || $t['eta'] < -1) { $sf->time_left = convertTimeText($t['eta']); } $sf->percent_done = $t['percentDone']; $sf->sharing = round($t['sharing'], 1); if ($t['status'] != 9 && $t['status'] != 5) { $sf->peers = $t['peers']; $sf->seeds = $t['seeds']; } if ($t['seeds'] >= 0) { $sf->seeds = $t['seeds']; } if ($t['peers'] >= 0) { $sf->peers = $t['peers']; } if ((double) $t['speedDown'] >= 0.0) { $sf->down_speed = formatBytesTokBMBGBTB($t['speedDown']) . "/s"; } if ((double) $t['speedUp'] >= 0.0) { $sf->up_speed = formatBytesTokBMBGBTB($t['speedUp']) . "/s"; } if ($t['status'] == 8) { $sf->percent_done = 100 + $t['sharing']; $sf->down_speed = " "; if (trim($sf->up_speed) == '') { $sf->up_speed = " "; } } if ($t['status'] == 9) { $sf->percent_done = 100 + $t['sharing']; $sf->up_speed = " "; $sf->down_speed = " "; } } else { //Stopped or finished... $sf->down_speed = ""; $sf->up_speed = ""; $sf->peers = ""; $sf->time_left = "0"; if ($t['eta'] < -1) { $sf->time_left = "Done in " . convertTimeText($t['eta']); } elseif ($sf->percent_done >= 100 && strpos($sf->time_left, 'Done') === false && strpos($sf->time_left, 'Finished') === false) { $sf->percent_done = 100; $sf->time_left = "Done!"; } if ($sf->sharing == 0) { $sf->sharing = round($t['sharing'], 1); } if (is_file($cfg["transfer_file_path"] . '/' . $transfer . ".pid")) { unlink($cfg["transfer_file_path"] . '/' . $transfer . ".pid"); } //if ($sf->percent_done < 100 && $sf->percent_done > 0) // $sf->percent_done = 0 - $sf->percent_done; } $sf->downtotal = $t['downTotal']; $sf->uptotal = $t['upTotal']; if ($sf->size == 0) { $sf->size = $t['size']; } if ($sf->seeds = -1) { } $sf->seeds = ''; if ($sf->write()) { $nbUpdate++; } } $nb = count($tfs); echo " updated {$nbUpdate}/{$nb} stat files.\n"; //fix globall sharekill to maximum of torrents sharekill, other torrent with lower sharekill will be stopped by this cron /* if (isset($max_share)) { $sharekill = getTransmissionShareKill(); if ($max_share > $sharekill) { //set vuze global sharekill to max sharekill value $rpc->session_set( array('seedRatioLimit' => round($max_share / 100, 2)) ); if ($cfg['debuglevel'] > 0) { $msg = $client.": changed vuze global sharekill from $sharekill to $max_share."; AuditAction($cfg["constants"]["debug"], $msg); echo $msg."\n"; } } } if ($max_ul > 0) { $vzmaxul = getTransmissionSpeedLimitUpload(); if ($cfg['max_upload_rate'] > 0 && $max_ul > 0) { $max_ul = min($max_ul, 1024.0 * $cfg['max_upload_rate']); } if ($vzmaxul != $max_ul) { $max_ul = $max_ul / 1024; $rpc->session_set( array('speed-limit-up' => $max_ul) ); if ($cfg['debuglevel'] > 0) { $msg = $client.": tranmission global speed-limit-up from $vzmaxul to $max_ul."; AuditAction($cfg["constants"]["debug"], $msg); echo $msg."\n"; } } } */ if ($bShowMissing) { return $missing; } }
/** * gets available port and sets port field * * @return boolean */ function _setClientPort() { global $cfg; $portString = netstatPortList(); $portAry = explode("\n", $portString); $this->port = intval($this->minport); while (1) { if (in_array($this->port, $portAry)) { $this->port += 1; } else { return true; } if ($this->port > $this->maxport) { // state $this->state = CLIENTHANDLER_STATE_ERROR; // message $msg = "All ports in use."; array_push($this->messages, $msg); AuditAction($cfg["constants"]["error"], $msg); $this->logMessage($msg . "\n", true); // write error to stat $sf = new StatFile($this->transfer, $this->owner); $sf->time_left = 'Error'; $sf->write(); // return return false; } } return false; }
/** * Resume Transfers * * @param $options * @param array $extra * @return mixed */ function _transfersResume($options = '', $extra = array()) { // parse options $optionsSet = $this->_parseOptions(array('p' => 1), $options, $extra); if ($optionsSet === false) { return false; } $profile = isset($optionsSet['p']) ? $optionsSet['p'][0] : null; $this->_outputMessage("Resuming all transfers" . (!empty($profile) ? " using profile " . $profile : '') . " ...\n"); // build args for _transferStart $newOptions = $this->_buildOptions('p', $optionsSet); // Pass-thru option 'p'. $transferList = getTransferArray(); $sf = new StatFile(""); foreach ($transferList as $transfer) { $sf->init($transfer); if (trim($sf->running) == 0) { $this->_transferStart($transfer, $newOptions[0], $newOptions[1]); } } }
/** * starts a client * * @param $transfer name of the transfer * @param $interactive (boolean) : is this a interactive startup with dialog ? * @param $enqueue (boolean) : enqueue ? */ function start($transfer, $interactive = false, $enqueue = false) { global $cfg; // set vars $this->_setVarsForTransfer($transfer); // log $this->logMessage($this->client . "-start : " . $transfer . "\n", true); // do mainline special-pre-start-checks // check to see if the path to the python script is valid if (!is_file($this->mainlineBin)) { $this->state = CLIENTHANDLER_STATE_ERROR; $msg = "path for tfmainline.py is not valid"; AuditAction($cfg["constants"]["error"], $msg); $this->logMessage($msg . "\n", true); array_push($this->messages, $msg); array_push($this->messages, "mainlineBin : " . $this->mainlineBin); // write error to stat $sf = new StatFile($this->transfer, $this->owner); $sf->time_left = 'Error'; $sf->write(); // return return false; } // init starting of client $this->_init($interactive, $enqueue, true, $cfg['enable_sharekill'] == 1); // only continue if init succeeded (skip start / error) if ($this->state != CLIENTHANDLER_STATE_READY) { if ($this->state == CLIENTHANDLER_STATE_ERROR) { $msg = "Error after init (" . $transfer . "," . $interactive . "," . $enqueue . ",true," . $cfg['enable_sharekill'] . ")"; array_push($this->messages, $msg); $this->logMessage($msg . "\n", true); } // return return false; } // build the command-string // note : order of args must not change for ps-parsing-code in // RunningTransferMainline $this->command = "cd " . tfb_shellencode($this->savepath) . ";"; $this->command .= " HOME=" . tfb_shellencode($cfg["path"]); $this->command .= "; export HOME;"; $this->command .= $this->umask; $this->command .= " nohup "; $this->command .= $this->nice; $this->command .= $cfg["pythonCmd"] . " -OO" . " " . tfb_shellencode($this->mainlineBin); $this->command .= " --tf_owner " . tfb_shellencode($this->owner); $this->command .= " --display_interval 1"; $this->command .= " --save_incomplete_in " . tfb_shellencode($this->savepath); $this->command .= " --save_in " . tfb_shellencode($this->savepath); $this->command .= " --die_when_done " . tfb_shellencode($this->runtime); $this->command .= " --seed_limit " . tfb_shellencode($this->sharekill_param); $this->command .= $this->drate != 0 ? " --max_download_rate " . tfb_shellencode($this->drate * 1024) : " --max_download_rate 125000000"; // 1 GBit local net = 125MB/s $this->command .= $this->rate != 0 ? " --max_upload_rate " . tfb_shellencode($this->rate * 1024) : " --max_upload_rate 125000000"; // 1 GBit local net = 125MB/s $this->command .= " --max_uploads " . tfb_shellencode($this->maxuploads); $this->command .= " --minport " . tfb_shellencode($this->port); $this->command .= " --maxport " . tfb_shellencode($this->maxport); $this->command .= " --rerequest_interval " . tfb_shellencode($this->rerequest); $this->command .= " --max_initiate " . tfb_shellencode($this->maxcons); if (!empty($this->skip_hash_check) && getTorrentDataSize($this->transfer) > 0) { $this->command .= " --no_check_hashes"; } if (strlen($cfg["btclient_mainline_options"]) > 0) { $this->command .= " " . $cfg["btclient_mainline_options"]; } $this->command .= " " . tfb_shellencode($this->transferFilePath); $this->command .= " 1>> " . tfb_shellencode($this->transferFilePath . ".log"); $this->command .= " 2>> " . tfb_shellencode($this->transferFilePath . ".log"); $this->command .= " &"; // start the client $this->_start(); }
/** * resets totals of a transfer * * @param $transfer name of the transfer * @param $delete boolean if to delete meta-file * @return array */ function resetTransferTotals($transfer, $delete = false) { global $cfg, $db, $transfers; $msgs = array(); $tid = getTransferHash($transfer); // delete meta-file if ($delete) { $ch = ClientHandler::getInstance(getTransferClient($transfer)); $ch->delete($transfer); if (count($ch->messages) > 0) { $msgs = array_merge($msgs, $ch->messages); } } else { // reset in stat-file $sf = new StatFile($transfer, getOwner($transfer)); $sf->uptotal = 0; $sf->downtotal = 0; $sf->write(); } // reset in db $sql = "DELETE FROM tf_transfer_totals WHERE tid = " . $db->qstr($tid); $db->Execute($sql); if ($db->ErrorNo() != 0) { dbError($sql); } // set transfers-cache cacheTransfersSet(); return $msgs; }
/** * starts a client * * @param $transfer name of the transfer * @param $interactive (boolean) : is this a interactive startup with dialog ? * @param $enqueue (boolean) : enqueue ? */ function start($transfer, $interactive = false, $enqueue = false) { global $cfg; // set vars $this->_setVarsForTransfer($transfer); // log $this->logMessage($this->client . "-start : " . $transfer . "\n", true); // do transmission special-pre-start-checks // check to see if the path to the transmission-bin is valid if (!is_executable($cfg["btclient_transmission_bin"])) { $this->state = CLIENTHANDLER_STATE_ERROR; $msg = "transmissioncli cannot be executed"; AuditAction($cfg["constants"]["error"], $msg); $this->logMessage($msg . "\n", true); array_push($this->messages, $msg); array_push($this->messages, "btclient_transmission_bin : " . $cfg["btclient_transmission_bin"]); // write error to stat $sf = new StatFile($this->transfer, $this->owner); $sf->time_left = 'Error'; $sf->write(); // return return false; } // init starting of client $this->_init($interactive, $enqueue, true, false); // only continue if init succeeded (skip start / error) if ($this->state != CLIENTHANDLER_STATE_READY) { if ($this->state == CLIENTHANDLER_STATE_ERROR) { $msg = "Error after init (" . $transfer . "," . $interactive . "," . $enqueue . ",true," . $cfg['enable_sharekill'] . ")"; array_push($this->messages, $msg); $this->logMessage($msg . "\n", true); } // return return false; } /* // workaround for bsd-pid-file-problem : touch file first if ((!$this->queue) && ($cfg["_OS"] == 2)) @touch($this->transferFilePath.".pid"); */ // build the command-string // note : order of args must not change for ps-parsing-code in // RunningTransferTransmission $this->command = "cd " . tfb_shellencode($this->savepath) . ";"; $this->command .= " HOME=" . tfb_shellencode($cfg["path"]) . "; export HOME;" . ($this->command .= $this->umask); $this->command .= " nohup "; $this->command .= $this->nice; $this->command .= tfb_shellencode($cfg["btclient_transmission_bin"]); $this->command .= " -d " . tfb_shellencode($this->drate); $this->command .= " -u " . tfb_shellencode($this->rate); $this->command .= " -p " . tfb_shellencode($this->port); $this->command .= " -W " . tfb_shellencode($this->runtime == "True" ? 1 : 0); $this->command .= " -L " . tfb_shellencode($this->sharekill_param); $this->command .= " -E 6"; $this->command .= " -O " . tfb_shellencode($this->owner); if (strlen($cfg["btclient_transmission_options"]) > 0) { $this->command .= " " . $cfg["btclient_transmission_options"]; } $this->command .= " " . tfb_shellencode($this->transferFilePath); $this->command .= " 1>> " . tfb_shellencode($this->transferFilePath . ".log"); $this->command .= " 2>> " . tfb_shellencode($this->transferFilePath . ".log"); $this->command .= " &"; // start the client $this->_start(); }
/** * injects a torrent * * @param $url * @return boolean */ function inject($url) { global $cfg; // set vars from the url $this->setVarsFromUrl($url); // write meta-file $resultSuccess = false; if ($handle = @fopen($this->transferFilePath, "w")) { $resultSuccess = @fwrite($handle, $this->url) !== false; @fclose($handle); } if ($resultSuccess) { // Make an entry for the owner AuditAction($cfg["constants"]["file_upload"], basename($this->transferFilePath)); // inject stat $sf = new StatFile($this->transfer); $sf->running = "2"; // file is new $sf->size = getTransferSize($this->transfer); if (!$sf->write()) { $this->state = CLIENTHANDLER_STATE_ERROR; $msg = "wget-inject-error when writing stat-file for transfer : " . $this->transfer; array_push($this->messages, $msg); AuditAction($cfg["constants"]["error"], $msg); $this->logMessage($msg . "\n", true); $resultSuccess = false; } } else { $this->state = CLIENTHANDLER_STATE_ERROR; $msg = "wget-metafile cannot be written : " . $this->transferFilePath; array_push($this->messages, $msg); AuditAction($cfg["constants"]["error"], $msg); $this->logMessage($msg . "\n", true); } // set transfers-cache cacheTransfersSet(); // return return $resultSuccess; }
/** * injects a transfer * * @param $transfer * @return boolean */ function injectTransfer($transfer) { global $cfg; $sf = new StatFile($transfer); $sf->running = "2"; // file is new $sf->size = getTransferSize($transfer); if ($sf->write()) { // set transfers-cache cacheTransfersSet(); return true; } else { AuditAction($cfg["constants"]["error"], "stat-file cannot be written when injecting : " . $transfer); return false; } }
/** * starts a client * * @param $transfer name of the transfer * @param $interactive (boolean) : is this a interactive startup with dialog ? * @param $enqueue (boolean) : enqueue ? */ function start($transfer, $interactive = false, $enqueue = false) { global $cfg; // set vars $this->_setVarsForTransfer($transfer); // log $this->logMessage($this->client . "-start : " . $transfer . "\n", true); // do tornado special-pre-start-checks // check to see if the path to the python script is valid if (!is_file($this->tornadoBin)) { $this->state = CLIENTHANDLER_STATE_ERROR; $msg = "path for tftornado.py is not valid"; AuditAction($cfg["constants"]["error"], $msg); $this->logMessage($msg . "\n", true); array_push($this->messages, $msg); array_push($this->messages, "tornadoBin : " . $this->tornadoBin); // write error to stat $sf = new StatFile($this->transfer, $this->owner); $sf->time_left = 'Error'; $sf->write(); // return return false; } // init starting of client $this->_init($interactive, $enqueue, true, $cfg['enable_sharekill'] == 1); // only continue if init succeeded (skip start / error) if ($this->state != CLIENTHANDLER_STATE_READY) { if ($this->state == CLIENTHANDLER_STATE_ERROR) { $msg = "Error after init (" . $transfer . "," . $interactive . "," . $enqueue . ",true," . $cfg['enable_sharekill'] . ")"; array_push($this->messages, $msg); $this->logMessage($msg . "\n", true); } // return return false; } // file-prio if ($cfg["enable_file_priority"]) { setFilePriority($transfer); } // pythonCmd $pyCmd = $cfg["pythonCmd"] . " -OO"; // build the command-string $skipHashCheck = ""; if (!empty($this->skip_hash_check) && getTorrentDataSize($transfer) > 0) { $skipHashCheck = " --check_hashes 0"; } $filePrio = ""; if (@file_exists($this->transferFilePath . ".prio")) { $priolist = explode(',', @file_get_contents($this->transferFilePath . ".prio")); $priolist = implode(',', array_slice($priolist, 1, $priolist[0])); $filePrio = " --priority " . tfb_shellencode($priolist); } // build the command-string // note : order of args must not change for ps-parsing-code in // RunningTransferTornado $this->command = ""; // Proxy Hack // $this->command .= 'export http_proxy=127.0.0.1:8118; HTTP_PROXY=$http_proxy;'; $this->command .= "cd " . tfb_shellencode($this->savepath) . ";"; $this->command .= " HOME=" . tfb_shellencode($cfg["path"]); $this->command .= "; export HOME;"; $this->command .= $this->umask; $this->command .= " nohup "; $this->command .= $this->nice; $this->command .= $pyCmd . " " . tfb_shellencode($this->tornadoBin); $this->command .= " " . tfb_shellencode($this->runtime); $this->command .= " " . tfb_shellencode($this->sharekill_param); $this->command .= " " . tfb_shellencode($this->owner); $this->command .= " " . tfb_shellencode($this->transferFilePath); $this->command .= " --responsefile " . tfb_shellencode($this->transferFilePath); $this->command .= " --display_interval 1"; $this->command .= " --max_download_rate " . tfb_shellencode($this->drate); $this->command .= " --max_upload_rate " . tfb_shellencode($this->rate); $this->command .= " --max_uploads " . tfb_shellencode($this->maxuploads); $this->command .= " --minport " . tfb_shellencode($this->port); $this->command .= " --maxport " . tfb_shellencode($this->maxport); $this->command .= " --rerequest_interval " . tfb_shellencode($this->rerequest); $this->command .= " --super_seeder " . tfb_shellencode($this->superseeder); $this->command .= " --max_connections " . tfb_shellencode($this->maxcons); $this->command .= $skipHashCheck; $this->command .= $filePrio; if (strlen($cfg["btclient_tornado_options"]) > 0) { $this->command .= " " . $cfg["btclient_tornado_options"]; } $this->command .= " 1>> " . tfb_shellencode($this->transferFilePath . ".log"); $this->command .= " 2>> " . tfb_shellencode($this->transferFilePath . ".log"); $this->command .= " &"; // start the client $this->_start(); }
/** * updateStatFiles * * @param $transfer string torrent name * @return boolean */ function updateStatFiles($transfer = "") { global $cfg, $db; $vuze = VuzeRPC::getInstance(); // do special-pre-start-checks if (!VuzeRPC::isRunning()) { return; } $tfs = $vuze->torrent_get_tf(); if (empty($tfs)) { return; } $sql = "SELECT hash, transfer, sharekill FROM tf_transfers WHERE type='torrent' AND client IN ('vuzerpc','azureus')"; if ($transfer != "") { //only update one transfer... $sql .= " AND transfer=" . $db->qstr($transfer); } else { //or a set of hashes $hashes = array("''"); foreach ($tfs as $hash => $t) { $hashes[] = "'" . strtolower($hash) . "'"; } $sql .= " AND hash IN (" . implode(',', $hashes) . ")"; } $recordset = $db->Execute($sql); $hashes = array(); $sharekills = array(); while (list($hash, $transfer, $sharekill) = $recordset->FetchRow()) { $hash = strtoupper($hash); $hashes[$hash] = $transfer; $sharekills[$hash] = $sharekill; } //convertTimeText require_once "inc/functions/functions.core.php"; foreach ($tfs as $hash => $t) { if (!isset($hashes[$hash])) { continue; } $transfer = $hashes[$hash]; $sf = new StatFile($transfer); $sf->running = $t['running']; if ($sf->running) { if ($t['eta'] > 0 || $t['eta'] < -1) { $sf->time_left = convertTimeText($t['eta']); } $sf->percent_done = $t['percentDone']; if ($t['status'] != 9 && $t['status'] != 5) { $sf->peers = $t['peers']; //(temp) force creation of pid file to fix first ones file_put_contents($cfg["transfer_file_path"] . '/' . $transfer . ".pid", "rpc"); } if ($t['seeds'] >= 0) { $sf->seeds = $t['seeds']; } if ($t['peers'] >= 0) { $sf->peers = $t['peers']; } if ((double) $t['speedDown'] > 0.0) { $sf->down_speed = formatBytesTokBMBGBTB($t['speedDown']) . "/s"; } if ((double) $t['speedUp'] > 0.0) { $sf->up_speed = formatBytesTokBMBGBTB($t['speedUp']) . "/s"; } if ($t['status'] == 8) { //seeding //$sf->percent_done = 100 + $t['sharing']; $sf->down_speed = ""; } if ($t['status'] == 9) { //seeding queued //$sf->percent_done = 100 + $t['sharing']; $sf->up_speed = ""; $sf->down_speed = ""; } } else { $sf->down_speed = ""; $sf->up_speed = ""; $sf->peers = ""; if ($t['eta'] < -1) { $sf->time_left = 'Done in ' . convertTimeText($t['eta']); } elseif ($sf->percent_done >= 100 && strpos($sf->time_left, 'Done') === false && strpos($sf->time_left, 'Finished') === false) { $sf->time_left = "Done!"; $sf->percent_done = 100; } if ($sf->percent_done < 100 && $sf->percent_done > 0) { //$sf->percent_done = 0 - $sf->percent_done; $sf->stop(); } } $sf->downtotal = $t['downTotal']; $sf->uptotal = $t['upTotal']; if (!$sf->size) { $sf->size = $t['size']; } if ($sf->seeds = -1) { } $sf->seeds = ''; $sf->write(); } //SHAREKILLS foreach ($tfs as $hash => $t) { if (isset($sharekills[$hash])) { if (($t['status'] == 8 || $t['status'] == 9) && $t['sharing'] > $sharekills[$hash]) { $transfer = $hashes[$hash]; if (!$vuze->torrent_stop_tf($hash)) { $msg = "transfer " . $transfer . " does not exist in vuze."; $this->logMessage($msg . "\n", true); AuditAction($cfg["constants"]["debug"], $this->client . "-stop : error {$hash} {$transfer}."); } else { // flag the transfer as stopped (in db) // log AuditAction($cfg["constants"]["stop_transfer"], $this->client . "-stat. : sharekill stopped {$transfer}"); stopTransferSettings($transfer); } } } } }
/** * _repairApp */ function _repairApp() { global $cfg, $db; // output $this->_outputMessage("repairing app...\n"); // sanity-check for transfers-dir if (!is_dir($cfg["transfer_file_path"])) { $this->state = MAINTENANCEANDREPAIR_STATE_ERROR; $msg = "invalid dir-settings. no dir : " . $cfg["transfer_file_path"]; array_push($this->messages, $msg); $this->_outputError($msg . "\n"); return false; } // delete pid-files of clients if ($dirHandle = opendir($cfg["transfer_file_path"])) { while (false !== ($file = readdir($dirHandle))) { if (strlen($file) > 3 && substr($file, -4, 4) == ".pid") { @unlink($cfg["transfer_file_path"] . $file); } } closedir($dirHandle); } // rewrite stat-files $arList = getTransferArray(); foreach ($arList as $transfer) { $sf = new StatFile($transfer, getOwner($transfer)); // output $this->_outputMessage("rewrite stat-file for " . $transfer . " ...\n"); $sf->running = 0; $sf->percent_done = -100.0; $sf->time_left = 'repaired'; $sf->down_speed = 0; $sf->up_speed = 0; $sf->seeds = 0; $sf->peers = 0; $sf->write(); // output $this->_outputMessage("done.\n"); } // set flags in db $this->_outputMessage("reset running-flag in database...\n"); $db->Execute("UPDATE tf_transfers SET running = '0'"); // output $this->_outputMessage("done.\n"); /* done */ $this->_outputMessage("repair app done.\n"); }
/** * starts a client * * @param $transfer name of the transfer * @param $interactive (boolean) : is this a interactive startup with dialog ? * @param $enqueue (boolean) : enqueue ? */ function start($transfer, $interactive = false, $enqueue = false) { global $cfg; // set vars $this->_setVarsForTransfer($transfer); // log $this->logMessage($this->client . "-start : " . $transfer . "\n", true); // do nzbperl special-pre-start-checks // check to see if the path to the nzbperl script is valid if (!is_file($this->nzbbin)) { $this->state = CLIENTHANDLER_STATE_ERROR; $msg = "path for tfnzbperl.pl is not valid"; AuditAction($cfg["constants"]["error"], $msg); $this->logMessage($msg . "\n", true); array_push($this->messages, $msg); array_push($this->messages, "nzbbin : " . $this->nzbbin); // write error to stat $sf = new StatFile($this->transfer, $this->owner); $sf->time_left = 'Error'; $sf->write(); // return return false; } // init starting of client $this->_init($interactive, $enqueue, false, false); // only continue if init succeeded (skip start / error) if ($this->state != CLIENTHANDLER_STATE_READY) { if ($this->state == CLIENTHANDLER_STATE_ERROR) { $msg = "Error after init (" . $transfer . "," . $interactive . "," . $enqueue . ",true," . $cfg['enable_sharekill'] . ")"; array_push($this->messages, $msg); $this->logMessage($msg . "\n", true); } // return return false; } // Build Command String (do not change order of last args !) $this->command = "cd " . tfb_shellencode($this->savepath) . ";"; $this->command .= " HOME=" . tfb_shellencode(substr($cfg["path"], 0, -1)); $this->command .= "; export HOME;"; $this->command .= $this->umask; $this->command .= " nohup "; $this->command .= $this->nice; $this->command .= $cfg['perlCmd']; $this->command .= " -I " . tfb_shellencode($cfg["docroot"] . "bin/lib"); $this->command .= " " . tfb_shellencode($this->nzbbin); $this->command .= " --conn " . tfb_shellencode($cfg['nzbperl_conn']); $this->command .= " --uudeview " . tfb_shellencode($cfg["bin_uudeview"]); $this->command .= $cfg['nzbperl_badAction'] ? " --insane --keepbrokenbin" : " --dropbad"; switch ($cfg['nzbperl_create']) { case 1: $this->command .= " --dlcreate"; break; case 2: $this->command .= " --dlcreategrp"; break; } $this->command .= " --dthreadct " . tfb_shellencode($cfg['nzbperl_threads']); $this->command .= " --speed " . tfb_shellencode($this->drate); $this->command .= " --server " . tfb_shellencode($cfg['nzbperl_server']); $this->command .= " --port " . tfb_shellencode($cfg['nzbperl_port']); if ($cfg["nzbperl_ssl"] == 1) { $this->command .= " --ssl"; } if ($cfg['nzbperl_user'] != "") { $this->command .= " --user " . tfb_shellencode($cfg['nzbperl_user']); $this->command .= " --pw " . tfb_shellencode($cfg['nzbperl_pw']); } if (strlen($cfg["nzbperl_options"]) > 0) { $this->command .= " " . $cfg['nzbperl_options']; } // do NOT change anything below (not even order) $this->command .= " --dlpath " . tfb_shellencode($this->savepath); $this->command .= " --tfuser " . tfb_shellencode($this->owner); $this->command .= " " . tfb_shellencode($this->transferFilePath); $this->command .= " 1>> " . tfb_shellencode($this->transferFilePath . ".log"); $this->command .= " 2>> " . tfb_shellencode($this->transferFilePath . ".log"); $this->command .= " &"; // state $this->state = CLIENTHANDLER_STATE_READY; // Start the client $this->_start(); }
/** * updateStatFiles * * @param $transfer string torrent name * @return boolean */ function updateStatFiles($transfer = "") { global $cfg, $db; //$rpc = Transmission::getInstance(); $tfs = $this->monitorRunningTransfers(); if (!is_array($tfs)) { return false; } $sql = "SELECT hash, transfer, sharekill FROM tf_transfers WHERE type='torrent' AND client = 'transmissionrpc'"; if ($transfer != "") { //only update one transfer... $sql .= " AND transfer=" . $db->qstr($transfer); } else { $hashes = array("''"); foreach ($tfs as $hash => $t) { $hashes[] = "'" . strtolower($hash) . "'"; } $sql .= " AND hash IN (" . implode(',', $hashes) . ")"; } $recordset = $db->Execute($sql); while (list($hash, $transfer, $sharekill) = $recordset->FetchRow()) { $hash = strtolower($hash); $hashes[$hash] = $transfer; $sharekills[$hash] = $sharekill; } //convertTimeText require_once "inc/functions/functions.core.php"; foreach ($tfs as $hash => $t) { if (!isset($hashes[$hash])) { continue; } $transfer = $hashes[$hash]; $sf = new StatFile($transfer); $sf->running = $t['running']; $sf->percent_done = round($t['percentDone'] * 100, 2); if ($t['status'] == 8 || $t['status'] == 9) { $sf->sharing = round($t['uploadRatio'] * 100, 2); } $sf->downtotal = $t['downloadedEver']; $sf->uptotal = $t['uploadedEver']; $sf->write(); } //SHAREKILLS Checks foreach ($tfs as $hash => $t) { if (!isset($sharekills[$hash])) { continue; } if (($t['status'] == 8 || $t['status'] == 9) && $t['uploadRatio'] * 100 > $sharekills[$hash]) { $transfer = $hashes[$hash]; if (stopTransmissionTransfer($hash)) { AuditAction($cfg["constants"]["stop_transfer"], $this->client . "-stat. : sharekill stopped {$transfer}"); stopTransferSettings($transfer); } } } return true; }
/** * clean stat file * * @param $transfer * @return boolean */ function cleanStoppedStatFile($transfer) { @unlink($this->transferFilePath . ".pid"); $sf = new StatFile($this->transfer, $this->owner); $sf->running = "0"; $sf->percent_done = 100; $sf->peers = ""; $sf->time_left = "Stopped"; $sf->down_speed = ""; $sf->up_speed = ""; //var_dump($sf);die(); return $sf->write(); }
/** * bulk * * @param $op */ function dispatcher_bulk($op) { global $cfg; // is enabled ? if ($cfg["enable_bulkops"] != 1) { AuditAction($cfg["constants"]["error"], "ILLEGAL ACCESS: " . $cfg["user"] . " tried to use " . $op); @error("bulkops are disabled", "", ""); } // messages $dispatcherMessages = array(); // op-switch switch ($op) { case "stop": $transferList = getTransferArray(); foreach ($transferList as $transfer) { if (isTransferRunning($transfer)) { if ($cfg['isAdmin'] || IsOwner($cfg["user"], getOwner($transfer))) { $ch = ClientHandler::getInstance(getTransferClient($transfer)); $ch->stop($transfer); if (count($ch->messages) > 0) { $dispatcherMessages = array_merge($dispatcherMessages, $ch->messages); } } } } break; case "resume": $transferList = getTransferArray(); $sf = new StatFile(""); foreach ($transferList as $transfer) { $sf->init($transfer); if (trim($sf->running) == 0 && !isTransferRunning($transfer)) { if ($cfg['isAdmin'] || IsOwner($cfg["user"], getOwner($transfer))) { $ch = ClientHandler::getInstance(getTransferClient($transfer)); $ch->start($transfer, false, false); if (count($ch->messages) > 0) { $dispatcherMessages = array_merge($dispatcherMessages, $ch->messages); } } } } break; case "start": $transferList = getTransferArray(); foreach ($transferList as $transfer) { if (!isTransferRunning($transfer)) { if ($cfg['isAdmin'] || IsOwner($cfg["user"], getOwner($transfer))) { $ch = ClientHandler::getInstance(getTransferClient($transfer)); $ch->start($transfer, false, false); if (count($ch->messages) > 0) { $dispatcherMessages = array_merge($dispatcherMessages, $ch->messages); } } } } break; } // error if messages if (count($dispatcherMessages) > 0) { @error("There were Problems", "", "", $dispatcherMessages); } }
function stop($transfer, $kill = false, $transferPid = 0) { global $cfg; $this->_setVarsForTransfer($transfer); AuditAction($cfg["constants"]["debug"], $this->client . "-stop : {$transfer}."); // stop the client $this->_stop($kill, $transferPid); // flag the transfer as stopped (in db) stopTransferSettings($transfer); //@ unlink($this->transferFilePath.".pid"); $stat = new StatFile($this->transfer, $this->owner); return $stat->stop(); }