/** * prepares start of a bittorrent-client. * prepares vars and other generic stuff * @param $torrent name of the torrent * @param $interactive (1|0) : is this a interactive startup with dialog ? */ function prepareStartTorrentClient($torrent, $interactive) { if ($this->status < 1) { $this->status = -1; $this->messages .= "Error. ClientHandler in wrong state on prepare-request."; return; } $this->skip_hash_check = ""; if ($interactive == 1) { // interactive, get vars from request vars $this->rate = getRequestVar('rate'); if (empty($this->rate)) { if ($this->rate != "0") { $this->rate = $this->cfg["max_upload_rate"]; } } $this->drate = getRequestVar('drate'); if (empty($this->drate)) { if ($this->drate != "0") { $this->drate = $this->cfg["max_download_rate"]; } } $this->superseeder = getRequestVar('superseeder'); if (empty($this->superseeder)) { $this->superseeder = "0"; } // should be 0 in most cases $this->runtime = getRequestVar('runtime'); if (empty($this->runtime)) { $this->runtime = $this->cfg["torrent_dies_when_done"]; } $this->maxuploads = getRequestVar('maxuploads'); if (empty($this->maxuploads)) { if ($this->maxuploads != "0") { $this->maxuploads = $this->cfg["max_uploads"]; } } $this->minport = getRequestVar('minport'); if (empty($this->minport)) { $this->minport = $this->cfg["minport"]; } $this->maxport = getRequestVar('maxport'); if (empty($this->maxport)) { $this->maxport = $this->cfg["maxport"]; } $this->maxcons = getRequestVar('maxcons'); if (empty($this->maxcons)) { $this->maxcons = $this->cfg["maxcons"]; } $this->rerequest = getRequestVar("rerequest"); if (empty($this->rerequest)) { $this->rerequest = $this->cfg["rerequest_interval"]; } $this->sharekill = getRequestVar('sharekill'); if ($this->runtime == "True") { $this->sharekill = "-1"; } if (empty($this->sharekill)) { if ($this->sharekill != "0") { $this->sharekill = $this->cfg["sharekill"]; } } $this->savepath = getRequestVar('savepath'); $this->skip_hash_check = getRequestVar('skiphashcheck'); } else { // non-interactive, load settings from db and set vars $this->rerequest = $this->cfg["rerequest_interval"]; $this->skip_hash_check = $this->cfg["skiphashcheck"]; $this->superseeder = 0; // load settings $settingsAry = loadTorrentSettings(urldecode($torrent)); $this->rate = $settingsAry["max_upload_rate"]; $this->drate = $settingsAry["max_download_rate"]; $this->runtime = $settingsAry["torrent_dies_when_done"]; $this->maxuploads = $settingsAry["max_uploads"]; $this->minport = $settingsAry["minport"]; $this->maxport = $settingsAry["maxport"]; $this->maxcons = $settingsAry["maxcons"]; $this->sharekill = $settingsAry["sharekill"]; $this->savepath = $settingsAry["savepath"]; // fallback-values if fresh-torrent is started non-interactive or // something else strange happened if ($this->rate == '') { $this->rate = $this->cfg["max_upload_rate"]; } if ($this->drate == '') { $this->drate = $this->cfg["max_download_rate"]; } if ($this->runtime == '') { $this->runtime = $this->cfg["torrent_dies_when_done"]; } if ($this->maxuploads == '') { $this->maxuploads = $this->cfg["max_uploads"]; } if ($this->minport == '') { $this->minport = $this->cfg["minport"]; } if ($this->maxport == '') { $this->maxport = $this->cfg["maxport"]; } if ($this->maxcons == '') { $this->maxcons = $this->cfg["maxcons"]; } if ($this->sharekill == '') { $this->sharekill = $this->cfg["sharekill"]; } } // queue if ($this->cfg["AllowQueing"]) { if (IsAdmin()) { $this->queue = getRequestVar('queue'); if ($this->queue == 'on') { $this->queue = "1"; } else { $this->queue = "0"; } } else { $this->queue = "1"; } } else { $this->queue = "0"; } // $this->torrent = urldecode($torrent); $this->alias = getAliasName($this->torrent); $this->owner = getOwner($this->torrent); if (empty($this->savepath)) { $this->savepath = $this->cfg['path'] . $this->owner . "/"; } // ensure path has trailing slash $this->savepath = checkDirPathString($this->savepath); // The following lines of code were suggested by Jody Steele jmlsteele@stfu.ca // This is to help manage user downloads by their user names // if the user's path doesnt exist, create it if (!is_dir($this->cfg["path"] . "/" . $this->owner)) { if (is_writable($this->cfg["path"])) { mkdir($this->cfg["path"] . "/" . $this->owner, 0777); } else { AuditAction($this->cfg["constants"]["error"], "Error -- " . $this->cfg["path"] . " is not writable."); if (IsAdmin()) { $this->status = -1; header("location: admin.php?op=configSettings"); return; } else { $this->status = -1; $this->messages .= "Error. TorrentFlux settings are not correct (path is not writable) -- please contact an admin."; } } } // create AliasFile object and write out the stat file include_once "AliasFile.php"; $this->af = AliasFile::getAliasFileInstance($this->cfg["torrent_file_path"] . $this->alias . ".stat", $this->owner, $this->cfg, $this->handlerName); //XFER: before a torrent start/restart save upload/download xfer to SQL $torrentTotals = getTorrentTotalsCurrent($this->torrent); saveXfer($this->owner, $torrentTotals["downtotal"] + 0, $torrentTotals["uptotal"] + 0); // update totals for this torrent updateTorrentTotals($this->torrent); // set param for sharekill if ($this->sharekill <= 0) { // nice, we seed forever $this->sharekill_param = 0; } else { // recalc sharekill $totalAry = getTorrentTotals(urldecode($torrent)); $upTotal = $totalAry["uptotal"] + 0; $torrentSize = $this->af->size + 0; $upWanted = $this->sharekill / 100 * $torrentSize; if ($upTotal >= $upWanted) { // we already have seeded at least // wanted percentage. continue to seed // forever is suitable in this case ~~ $this->sharekill_param = 0; } else { // not done seeding wanted percentage $this->sharekill_param = (int) ($this->sharekill - $upTotal / $torrentSize * 100); // the type-cast may have floored the value. (tornado lacks // precision because only (really?) accepting percentage-values) // better to seed more than less so we add a percent in case ;) if ($upWanted % $upTotal != 0) { $this->sharekill_param += 1; } // sanity-check. if ($this->sharekill_param <= -1) { $this->sharekill_param = 0; } } } if ($this->cfg["AllowQueing"]) { if ($this->queue == "1") { $this->af->QueueTorrentFile(); // this only writes out the stat file (does not start torrent) } else { if ($this->setClientPort() === false) { return; } $this->af->StartTorrentFile(); // this only writes out the stat file (does not start torrent) } } else { if ($this->setClientPort() === false) { return; } $this->af->StartTorrentFile(); // this only writes out the stat file (does not start torrent) } $this->status = 2; }
/** * deletes a torrent * * @param $torrent name of the torrent * @param $alias_file alias-file of the torrent * @return boolean of success */ function deleteTorrent($torrent, $alias_file) { $delfile = $torrent; global $cfg; //$alias_file = getRequestVar('alias_file'); $torrentowner = getOwner($delfile); if ($cfg["user"] == $torrentowner || IsAdmin()) { include_once "AliasFile.php"; // we have more meta-files than .torrent. handle this. if (substr(strtolower($torrent), -8) == ".torrent") { // this is a torrent-client $btclient = getTorrentClient($delfile); $af = AliasFile::getAliasFileInstance($cfg['torrent_file_path'] . $alias_file, $torrentowner, $cfg, $btclient); // update totals for this torrent updateTorrentTotals($delfile); // remove torrent-settings from db deleteTorrentSettings($delfile); // client-proprietary leftovers include_once "ClientHandler.php"; $clientHandler = ClientHandler::getClientHandlerInstance($cfg, $btclient); $clientHandler->deleteTorrentCache($torrent); } else { if (substr(strtolower($torrent), -4) == ".url") { // this is wget. use tornado statfile $alias_file = str_replace(".url", "", $alias_file); $af = AliasFile::getAliasFileInstance($cfg['torrent_file_path'] . $alias_file, $cfg['user'], $cfg, 'tornado'); } else { // this is "something else". use tornado statfile as default $af = AliasFile::getAliasFileInstance($cfg['torrent_file_path'] . $alias_file, $cfg['user'], $cfg, 'tornado'); } } if ($cfg['enable_xfer'] != 0) { //XFER: before torrent deletion save upload/download xfer data to SQL $torrentTotals = getTorrentTotalsCurrent($delfile); saveXfer($torrentowner, $torrentTotals["downtotal"] + 0, $torrentTotals["uptotal"] + 0); } // torrent+stat @unlink($cfg["torrent_file_path"] . $delfile); @unlink($cfg["torrent_file_path"] . $alias_file); // try to remove the QInfo if in case it was queued. @unlink($cfg["torrent_file_path"] . "queue/" . $alias_file . ".Qinfo"); // try to remove the pid file @unlink($cfg["torrent_file_path"] . $alias_file . ".pid"); @unlink($cfg["torrent_file_path"] . getAliasName($delfile) . ".prio"); AuditAction($cfg["constants"]["delete_torrent"], $delfile); return true; } else { AuditAction($cfg["constants"]["error"], $cfg["user"] . " attempted to delete " . $delfile); return false; } }
/** * prepares start of a bittorrent-client. * prepares vars and other generic stuff * @param $torrent name of the torrent * @param $interactive (1|0) : is this a interactive startup with dialog ? */ function prepareStartTorrentClient($torrent, $interactive) { if ($this->state < 1) { $this->state = -1; $this->messages .= "Error. ClientHandler in wrong state on prepare-request."; return; } $this->skip_hash_check = ""; if ($interactive == 1) { // interactive, get vars from request vars $this->rate = getRequestVar('rate'); if (empty($this->rate)) { if ($this->rate != "0") { $this->rate = $this->cfg["max_upload_rate"]; } } $this->drate = getRequestVar('drate'); if (empty($this->drate)) { if ($this->drate != "0") { $this->drate = $this->cfg["max_download_rate"]; } } $this->superseeder = getRequestVar('superseeder'); if (empty($this->superseeder)) { $this->superseeder = "0"; } // should be 0 in most cases $this->runtime = getRequestVar('runtime'); if (empty($this->runtime)) { $this->runtime = $this->cfg["torrent_dies_when_done"]; } $this->maxuploads = getRequestVar('maxuploads'); if (empty($this->maxuploads)) { if ($this->maxuploads != "0") { $this->maxuploads = $this->cfg["max_uploads"]; } } $this->minport = getRequestVar('minport'); if (empty($this->minport)) { $this->minport = $this->cfg["minport"]; } $this->maxport = getRequestVar('maxport'); if (empty($this->maxport)) { $this->maxport = $this->cfg["maxport"]; } $this->maxcons = getRequestVar('maxcons'); if (empty($this->maxcons)) { $this->maxcons = $this->cfg["maxcons"]; } $this->rerequest = getRequestVar("rerequest"); if (empty($this->rerequest)) { $this->rerequest = $this->cfg["rerequest_interval"]; } $this->sharekill = getRequestVar('sharekill'); if ($this->runtime == "True") { $this->sharekill = "-1"; } if (empty($this->sharekill)) { if ($this->sharekill != "0") { $this->sharekill = $this->cfg["sharekill"]; } } $this->savepath = getRequestVar('savepath'); $this->skip_hash_check = getRequestVar('skiphashcheck'); } else { // non-interactive, load settings from db and set vars $this->rerequest = $this->cfg["rerequest_interval"]; $this->skip_hash_check = $this->cfg["skiphashcheck"]; $this->superseeder = 0; // load settings $settingsAry = loadTorrentSettings(urldecode($torrent)); $this->rate = $settingsAry["max_upload_rate"]; $this->drate = $settingsAry["max_download_rate"]; $this->runtime = $settingsAry["torrent_dies_when_done"]; $this->maxuploads = $settingsAry["max_uploads"]; $this->minport = $settingsAry["minport"]; $this->maxport = $settingsAry["maxport"]; $this->maxcons = $settingsAry["maxcons"]; $this->sharekill = $settingsAry["sharekill"]; $this->savepath = $settingsAry["savepath"]; // fallback-values if fresh-torrent is started non-interactive or // something else strange happened if ($this->rate == '') { $this->rate = $this->cfg["max_upload_rate"]; } if ($this->drate == '') { $this->drate = $this->cfg["max_download_rate"]; } if ($this->runtime == '') { $this->runtime = $this->cfg["torrent_dies_when_done"]; } if ($this->maxuploads == '') { $this->maxuploads = $this->cfg["max_uploads"]; } if ($this->minport == '') { $this->minport = $this->cfg["minport"]; } if ($this->maxport == '') { $this->maxport = $this->cfg["maxport"]; } if ($this->maxcons == '') { $this->maxcons = $this->cfg["maxcons"]; } if ($this->sharekill == '') { $this->sharekill = $this->cfg["sharekill"]; } } // queue if ($this->cfg["AllowQueing"]) { if (IsAdmin()) { $this->queue = getRequestVar('queue'); if ($this->queue == 'on') { $this->queue = "1"; } else { $this->queue = "0"; } } else { $this->queue = "1"; } } else { $this->queue = "0"; } // $this->torrent = urldecode($torrent); $this->alias = getAliasName($this->torrent); $this->owner = getOwner($this->torrent); if (empty($this->savepath)) { $this->savepath = $this->cfg['path'] . $this->owner . "/"; } // ensure path has trailing slash $this->savepath = checkDirPathString($this->savepath); // check target-directory, create if not present if (!checkDirectory($this->savepath, 0777)) { AuditAction($this->cfg["constants"]["error"], "Error checking " . $this->savepath . "."); $this->state = -1; $this->messages .= "Error. TorrentFlux settings are not correct (path-setting)."; global $argv; if (isset($argv)) { die($this->messages); } else { if (IsAdmin()) { @header("location: admin.php?op=configSettings"); exit; } else { $this->messages .= " please contact an admin."; showErrorPage($this->messages); } } } // create AliasFile object and write out the stat file include_once "AliasFile.php"; $this->af = AliasFile::getAliasFileInstance($this->cfg["torrent_file_path"] . $this->alias . ".stat", $this->owner, $this->cfg, $this->handlerName); // set param for sharekill $this->sharekill = intval($this->sharekill); if ($this->sharekill == 0) { // nice, we seed forever $this->sharekill_param = 0; } elseif ($this->sharekill > 0) { // recalc sharekill // sanity-check. catch "data-size = 0". $transferSize = intval($this->af->size); if ($transferSize > 0) { $totalAry = getTorrentTotals($this->torrent); $upTotal = $totalAry["uptotal"] + 0; $downTotal = $totalAry["downtotal"] + 0; $upWanted = $this->sharekill / 100 * $transferSize; $sharePercentage = $upTotal / $transferSize * 100; if ($upTotal >= $upWanted && $downTotal >= $transferSize) { // we already have seeded at least wanted percentage. // skip start of client // set state $this->state = 1; // message $this->messages = "skipping start of transfer " . $this->torrent . " due to share-ratio (has: " . @number_format($sharePercentage, 2) . " ; set:" . $this->sharekill . ")"; // DEBUG : log the messages AuditAction($this->cfg["constants"]["debug"], $this->messages); // return return; } else { // not done seeding wanted percentage $this->sharekill_param = intval(ceil($this->sharekill - $sharePercentage)); // sanity-check. if ($this->sharekill_param < 1) { $this->sharekill_param = 1; } } } else { $this->messages = "data-size is 0 when recalcing share-kill for " . $this->torrent . ". setting sharekill absolute to " . $this->sharekill; AuditAction($this->cfg["constants"]["error"], $this->messages); $this->sharekill_param = $this->sharekill; } } else { $this->sharekill_param = $this->sharekill; } // set port if start (not queue) if (!($this->cfg["AllowQueing"] && $this->queue == "1")) { if ($this->setClientPort() === false) { return; } } //XFER: before a torrent start/restart save upload/download xfer to SQL $torrentTotals = getTorrentTotalsCurrent($this->torrent); saveXfer($this->owner, $torrentTotals["downtotal"] + 0, $torrentTotals["uptotal"] + 0); // update totals for this torrent updateTorrentTotals($this->torrent); // write stat-file if ($this->cfg["AllowQueing"] && $this->queue == "1") { $this->af->QueueTorrentFile(); } else { $this->af->StartTorrentFile(); } // set state $this->state = 2; }