function recv_bvalue($s) { $v = bdec(recv_string($s)); if ($v['value']['failure reason']['value']) { die($v['value']['failure reason']['value']); } return $v; }
function setUser($username, $userid) { $this->dict->hashSetter('[\'value\'][\'created by\']', bdec(benc_str("{$username}"))); $this->dict->hashSetter('[\'value\'][\'publisher\']', bdec(benc_str("{$username}"))); $this->dict->hashSetter('[\'value\'][\'publisher.utf-8\']', bdec(benc_str("username"))); $this->dict->hashSetter('[\'value\'][\'publisher-url\']', bdec(benc_str(DEFAULTBASEURL . "/users/view/{$userid}"))); $this->dict->hashSetter('[\'value\'][\'publisher-url.utf-8\']', bdec(benc_str(DEFAULTBASEURL . "/users/view/{$userid}"))); }
function bdec($str, &$_len = 0) { $type = substr($str, 0, 1); if (is_numeric($type)) { $type = 's'; } switch ($type) { case 'i': //integer $p = strpos($str, 'e'); $_len = $p + 1; //lenght of bencoded data return intval(substr($str, 1, $p - 1)); break; case 's': //string $p = strpos($str, ':'); $len = substr($str, 0, $p); $_len = $len + $p + 1; //lenght of bencoded data return substr($str, $p + 1, $len); break; case 'l': //list $l = 1; $ret_array = array(); while (substr($str, $l, 1) != 'e') { $ret_array[] = bdec(substr($str, $l), $len); $l += $len; } $_len = $l + 1; //lenght of bencoded data return $ret_array; break; case 'd': //dictionary $l = 1; $ret_array = array(); while (substr($str, $l, 1) != 'e') { $var = bdec(substr($str, $l), $len); $l += $len; $ret_array[$var] = bdec(substr($str, $l), $len); $l += $len; } $_len = $l + 1; //lenght of bencoded data return $ret_array; break; } }
function bdec_dict($s) { if ($s[0] != "d") { return; } $sl = strlen($s); $i = 1; $v = array(); $ss = "d"; for (;;) { if ($i >= $sl) { return; } if ($s[$i] == "e") { break; } $ret = bdec(substr($s, $i)); if (!isset($ret) || !is_array($ret) || $ret["type"] != "string") { return; } $k = $ret["value"]; $i += $ret["strlen"]; $ss .= $ret["string"]; if ($i >= $sl) { return; } $ret = bdec(substr($s, $i)); if (!isset($ret) || !is_array($ret)) { return; } $v[$k] = $ret; $i += $ret["strlen"]; $ss .= $ret["string"]; } $ss .= "e"; return array('type' => "dictionary", 'value' => $v, 'strlen' => strlen($ss), 'string' => $ss); }
bark("filename error"); } $ffe = implode("/", $ffa); $filelist[] = array($ffe, $ll); } $type = "multi"; } /* Private Tracker mod code goes below */ $info[$i]['value']['source']['type'] = "string"; $info[$i]['value']['source']['value'] = $SITENAME; $info[$i]['value']['source']['strlen'] = strlen($info[$i]['value']['source']['value']); $info[$i]['value']['private']['type'] = "integer"; $info[$i]['value']['private']['value'] = 1; $dict[$i]['value']['info'] = $info[$i]; $dict[$i] = benc($dict[$i]); $dict[$i] = bdec($dict[$i]); list($ann[$i], $info[$i]) = dict_check($dict[$i], "announce(string):info"); unset($dict['value']['created by']); $infohash[$i] = pack("H*", sha1($info[$i]["string"])); /* ...... end of Private Tracker mod */ $torrent[$i] = str_replace("_", " ", $torrent[$i]); $torrent[$i] = str_replace("'", " ", $torrent[$i]); $torrent[$i] = str_replace("\"", " ", $torrent[$i]); $torrent[$i] = str_replace(",", " ", $torrent[$i]); $nfo[$i] = sqlesc(str_replace("\r\r\n", "\r\n", @file_get_contents($nfofilename[$i]))); $first = $shortfname[$i][1]; $second = $dname[$i]; $third = $torrent[$i][1]; $ret = mysql_query("INSERT INTO torrents (search_text, filename, owner, visible, info_hash, name, size, numfiles, type, descr, ori_descr, category, save_as, added, last_action, nfo) VALUES (" . implode(",", array_map("sqlesc", array(searchfield("{$first} {$second} {$third}"), $fname[$i], $CURUSER["id"], "no", $infohash[$i], $torrent[$i][1], $totallen, count($filelist[$i]), $type, $descr, $descr, $cat[$i], $dname[$i]))) . ", '" . get_date_time() . "', '" . get_date_time() . "', {$nfo[$i]})"); // //////new torrent upload detail sent to shoutbox////////// if ($CURUSER["anonymous"] == 'yes') {
$filelist[] = array($ffe, $ll); } $type = "multi"; } $dict['value']['announce'] = bdec(benc_str(get_protocol_prefix() . $announce_urls[0])); // change announce url to local $dict['value']['info']['value']['private'] = bdec('i1e'); // add private tracker flag //The following line requires uploader to re-download torrents after uploading //even the torrent is set as private and with uploader's passkey in it. $dict['value']['info']['value']['source'] = bdec(benc_str("[{$BASEURL}] {$SITENAME}")); unset($dict['value']['announce-list']); // remove multi-tracker capability unset($dict['value']['nodes']); // remove cached peers (Bitcomet & Azareus) $dict = bdec(benc($dict)); // double up on the becoding solves the occassional misgenerated infohash list($ann, $info) = dict_check($dict, "announce(string):info"); $infohash = pack("H*", sha1($info["string"])); function hex_esc2($matches) { return sprintf("%02x", ord($matches[0])); } //die(phpinfo()); //die("magic:" . get_magic_quotes_gpc()); //die("\\' pos:" . strpos($infohash,"\\") . ", after sqlesc:" . (strpos(sqlesc($infohash),"\\") == false ? "gone" : strpos(sqlesc($infohash),"\\"))); //die(preg_replace_callback('/./s', "hex_esc2", $infohash)); // ------------- start: check upload authority ------------------// $allowtorrents = user_can_upload("torrents"); $allowspecial = user_can_upload("music"); $catmod = get_single_value("categories", "mode", "WHERE id=" . sqlesc($catid));
function bdec_list($s) { if ($s[0] != "l") { return; } $sl = strlen($s); $i = 1; $v = array(); $ss = "l"; for (;;) { if ($i >= $sl) { return; } if ($s[$i] == "e") { break; } $ret = bdec(substr($s, $i)); if (!isset($ret) || !is_array($ret)) { return; } $v[] = $ret; $i += $ret["strlen"]; $ss .= $ret["string"]; } $ss .= "e"; return array("type" => "list", "value" => $v, "strlen" => strlen($ss), "string" => $ss); }
// moddifed logginorreturn by retro//Remember to change the following line to match your server print "<html><h1>Not Found</h1><p>The requested URL /{$_SERVER['PHP_SELF']} was not found on this server.</p><hr /><address>Apache/1.1.11 " . $SITENAME . " Server at " . $_SERVER['SERVER_NAME'] . " Port 80</address></body></html>\n"; die; } if (!preg_match(':^/(\\d{1,10})/(.+)\\.torrent$:', $_SERVER["PATH_INFO"], $matches)) { httperr(); } $id = 0 + $matches[1]; if (!$id) { httperr(); } $res = mysql_query("SELECT name FROM torrents WHERE id = {$id}") or sqlerr(__FILE__, __LINE__); $row = mysql_fetch_assoc($res); $fn = "{$torrent_dir}/{$id}.torrent"; if (!$row || !is_file($fn) || !is_readable($fn)) { httperr(); } mysql_query("UPDATE torrents SET hits = hits + 1 WHERE id = {$id}"); require_once "include/benc.php"; if (strlen($CURUSER['passkey']) != 32) { $CURUSER['passkey'] = md5($CURUSER['username'] . get_date_time() . $CURUSER['passhash']); mysql_query("UPDATE users SET passkey='{$CURUSER['passkey']}' WHERE id={$CURUSER['id']}"); } $dict = bdec_file($fn, 1024 * 1024); $dict['value']['announce']['value'] = "{$announce_urls['0']}"; $dict['value']['announce']['string'] = strlen($dict['value']['announce']['value']) . ":" . $dict['value']['announce']['value']; $dict['value']['announce']['strlen'] = strlen($dict['value']['announce']['string']); $dict['value']['created by'] = bdec(benc_str("" . $CURUSER['username'] . "")); //header('Content-Disposition: attachment; filename="'.$torrent['filename'].'"'); header("Content-Type: application/x-bittorrent"); print benc($dict);
$recommended = unesc($_POST['recommended']); $tube = unesc($_POST['tube']); $url = unesc($_POST['url']); $dict['value']['announce'] = bdec(benc_str($announce_urls[0])); // change announce url to local $dict['value']['info']['value']['private'] = bdec('i1e'); // add private tracker flag $dict['value']['info']['value']['source'] = bdec(benc_str("[{$DEFAULTBASEURL}] {$SITENAME}")); // add link for bitcomet users unset($dict['value']['announce-list']); // remove multi-tracker capability unset($dict['value']['nodes']); // remove cached peers (Bitcomet & Azareus) $dict = bdec(benc($dict)); // double up on the becoding solves the occassional misgenerated infohash $dict['value']['comment'] = bdec(benc_str("In using this torrent you are bound by the '{$SITENAME}' Confidentiality Agreement By Law")); // change torrent comment list($ann, $info) = dict_check($dict, "announce(string):info"); unset($dict['value']['created by']); //Null the created_by field/// $infohash = pack("H*", sha1($info["string"])); $uclass = $CURUSER["class"]; // Replace punctuation characters with spaces $torrent = str_replace("_", " ", $torrent); // /////////pretime//////// /* $pre = getpre($torrent,1); $timestamp = strtotime($pre); $tid = time(); if (empty($pre)) { $predif = "N/A";
// remove cached peers (Bitcomet & Azareus) unset($dict['value']['info']['value']['crc32']); // remove crc32 unset($dict['value']['info']['value']['ed2k']); // remove ed2k unset($dict['value']['info']['value']['md5sum']); // remove md5sum unset($dict['value']['info']['value']['sha1']); // remove sha1 unset($dict['value']['info']['value']['tiger']); // remove tiger unset($dict['value']['azureus_properties']); // remove azureus properties $dict = bdec(benc($dict)); // double up on the becoding solves the occassional misgenerated infohash $dict['value']['comment'] = bdec(benc_str("Torrent created for SceneBits")); // change torrent comment list($ann, $info) = dict_check($dict, "announce(string):info"); #End of Private Tracker Patch $infohash = pack("H*", sha1($info["string"])); // Replace punctuation characters with spaces $pretime = 0 + @file_get_contents("http://xxxxx/abcd.php?name=" . trim($torrent)); $poster = isset($_POST['poster']) ? unesc($_POST['poster']) : ""; //$torrent = str_replace("_", " ", $torrent); $anonymous = 'yes'; $ret = mysql_query("INSERT INTO torrents (search_text, filename, owner, visible, scene, freeleech, url, anonymous, vip, info_hash, poster, name, size, numfiles, type, descr, ori_descr, category, save_as, added, last_action, nfo, pretime) VALUES (" . implode(",", array_map("sqlesc", array(searchfield("{$shortfname} {$dname} {$torrent}"), $fname, $CURUSER["id"], "no", $scene, $freeleech, $url, $anonymous, $vip, $infohash, $poster, $torrent, $totallen, count($filelist), $type, $descr, $descr, 0 + $_POST["type"], $dname))) . ", '" . get_date_time() . "', '" . get_date_time() . "', {$nfo}, '" . $pretime . "')"); if (!$ret) { if (mysql_errno() == 1062) { bark("torrent already uploaded!"); } bark("mysql puked: " . mysql_error());
public function upload($uploaded_file, $post) { if ($this->user->isUploadBanned()) { throw new Exception("Du är bannad ifrån att kunna ladda upp torrents.", 401); } $max_torrent_size = 10000000; ini_set("upload_max_filesize", $max_torrent_size); include 'benc.php'; if ($post["category"] < 1 || $post["category"] > 12) { throw new Exception('Ogiltig kategori.'); } if (!preg_match("/^\\d+\$/", $post["reqid"])) { throw new Exception('Ogiltig sektion.'); } if (!preg_match("/\\.torrent\$/", $uploaded_file["name"], $match)) { throw new Exception('Ingen torrent-fil.'); } if (!is_uploaded_file($uploaded_file["tmp_name"])) { throw new Exception('Filen kunde inte laddas upp.'); } if (!filesize($uploaded_file["tmp_name"])) { throw new Exception('Filen verkar vara tom.'); } if ($post["category"] == 8 && $post["reqid"] == 0 && ($post["channel"] == 0 || $post["program"] == 0)) { throw new Exception('Du måste välja kanal och program för ny Svensk TV.'); } if ($post["reqid"] > 2) { $request = $this->requests->get($post["reqid"]); if ($this->user->getId() == $request["user"]["id"]) { throw new Exception("Du får inte fylla din egna request", 400); } if ($request["filled"] == 1) { throw new Exception("Requesten är redan fylld.", 400); } } $name = preg_replace("/\\.torrent\$/", '', $uploaded_file["name"]); $category = $post["category"]; $reqid = $post["reqid"]; $anonymousUpload = $post["anonymousUpload"]; $nfo = $post["nfo"]; $imdbId = $post["imdbId"]; $p2p = $post["p2p"]; $freeleech = 0; $stereoscopic = 0; $swesub = 0; if (in_array($category, array(1, 2, 3, 10, 11))) { $swesub = 1; } if ($post["swesub"] == 1 && in_array($category, array(4, 5, 6, 7))) { $swesub = 1; } /* SWE-TV */ $tvProgramId = $post["program"] ?: 0; $tvChannel = $post["channel"] ?: 0; $tvProgram = ''; $tvEpisode = ''; $tvInfo = ''; $tvTime = 0; if ($category == 8 && $tvProgramId > 0 && $tvChannel > 0) { /* Manual entered program */ if ($tvProgramId == 1) { $tvProgram = $post["programTitle"]; $tvTime = strtotime($post["programDate"]); if (strlen($tvProgram) < 2) { throw new Exception('Programnamnet för kort.'); } $tvProgramId = 2; } else { $sweTv = $this->sweTv->getProgram($tvProgramId); if (!$sweTv) { throw new Exception('Ogiltigt TV-program valt.'); } $tvProgram = $sweTv["program"]; $tvEpisode = $sweTv["episod"]; $tvInfo = $sweTv["info"]; $tvTime = $sweTv["datum"]; } } if ($this->user->getClass() < User::CLASS_UPLOADER && $reqid == 0) { throw new Exception('Bara uppladdare kan ladda upp på nytt.'); } $sth = $this->db->prepare("SELECT COUNT(*) FROM torrents WHERE name = ?"); $sth->execute(array($name)); $arr = $sth->fetch(); if ($arr[0] == 1) { throw new Exception('Dublett. Releasen finns redan på sidan.'); } $sth = $this->db->prepare("SELECT COUNT(*) FROM packfiles WHERE filename = ?"); $sth->execute(array($name)); $arr = $sth->fetch(); if ($arr[0] == 1) { throw new Exception('Dublett. Releasen finns redan inuti ett pack.'); } $sth = $this->db->prepare("SELECT comment FROM banned WHERE namn = ?"); $sth->execute(array($name)); while ($arr = $sth->fetch(PDO::FETCH_ASSOC)) { throw new Exception('Releasen är bannad med anledning: ' . $arr["comment"]); } $dict = bdec_file($uploaded_file["tmp_name"], $max_torrent_size); if (!isset($dict)) { throw new Exception('Fel på .torrent-filen.'); } function dict_check($d, $s) { if ($d["type"] != "dictionary") { throw new Exception("Filen är inte en torrent-fil"); } $a = explode(":", $s); $dd = $d["value"]; $ret = array(); foreach ($a as $k) { unset($t); if (preg_match('/^(.*)\\((.*)\\)$/', $k, $m)) { $k = $m[1]; $t = $m[2]; } if (isset($t)) { if ($dd[$k]["type"] != $t) { throw new Exception("Torrent-filen saknar troligtvis announce/tracker url."); } $ret[] = $dd[$k]["value"]; } else { $ret[] = $dd[$k]; } } return $ret; } function dict_get($d, $k, $t) { if ($d["type"] != "dictionary") { throw new Exception("Fel på torrent-fil."); } $dd = $d["value"]; if (!isset($dd[$k])) { return; } $v = $dd[$k]; if ($v["type"] != $t) { throw new Exception("Fel på torrent-fil."); } return $v["value"]; } list($ann, $info) = dict_check($dict, "announce(string):info"); list($dname, $plen, $pieces) = dict_check($info, "name(string):piece length(integer):pieces(string)"); if (strlen($pieces) % 20 != 0) { throw new Exception("Fel på torrent-fil."); } $filelist = array(); $totallen = dict_get($info, "length", "integer"); if (isset($totallen)) { $filelist[] = array($dname, $totallen); $type = "single"; } else { $flist = dict_get($info, "files", "list"); if (!isset($flist)) { throw new Exception("Saknar både längd och filer."); } if (!count($flist)) { throw new Exception("Torrent saknar filer."); } $totallen = 0; foreach ($flist as $fn) { list($ll, $ff) = dict_check($fn, "length(integer):path(list)"); $totallen += $ll; $ffa = array(); foreach ($ff as $ffe) { if ($ffe["type"] != "string") { throw new Exception("Fel på filnamn."); } $ffa[] = $ffe["value"]; } if (!count($ffa)) { throw new Exception("Fel på filnamn."); } $ffe = implode("/", $ffa); $filelist[] = array($ffe, $ll); } $type = "multi"; } $foundBanned = array(); $bannedfiles = array(".DS_Store", "._.DS_Store", "ufxpcrc.log", "Thumbs.db", ".checked", ".message", "desktop.ini", "Default.PLS", ".url", ".html", "imdb.nfo", ".missing", "-missing", ".torrent"); foreach ($filelist as $file) { foreach ($bannedfiles as $bfile) { if (preg_match("/" . $bfile . "\$/", $file[0])) { $foundBanned[] = $file[0]; } } } if (count($foundBanned) > 0) { $files = ''; foreach ($foundBanned as $f) { $files .= '\'' . $f . '\', '; } $this->adminlog->create("[b]" . $this->user->getUsername() . "[/b] försökte ladda upp [i]" . $name . "[/i] innehållandes otllåtna skräpfil(er): [b]" . $files . "[/b]."); throw new Exception("Din torrent innehåller följande otillåtna skräpfiler: [b]" . $files); } if (($txt = $this->detectMissingFiles($filelist)) != false) { $this->adminlog->create('[b]' . $this->user->getUsername() . '[/b] försökte ladda upp [i]' . $name . '[/i] men: ' . $txt); throw new Exception("Fattas filer i torrent: " . $txt); } $info['value']['source']['type'] = "string"; $info['value']['source']['value'] = Helper::$siteName; $info['value']['source']['strlen'] = strlen($info['value']['source']['value']); $info['value']['private']['type'] = "integer"; $info['value']['private']['value'] = 1; $dict['value']['info'] = $info; $dict = benc($dict); $dict = bdec($dict); list($ann, $info) = dict_check($dict, "announce(string):info"); $infohash = bin2hex(pack("H*", sha1($info["string"]))); $sth = $this->db->prepare("SELECT COUNT(*) FROM torrents WHERE info_hash = ?"); $sth->bindParam(1, $infohash, PDO::PARAM_STR); $sth->execute(); $arr = $sth->fetch(); if ($arr[0] == 1) { throw new Exception('Dublett. Releasen finns redan på sidan.'); } $pre = Helper::preCheck($name); if (!$pre) { $pre = 0; } else { if ($pre > time()) { $pre = time() - 100; } /* Use pre-time to determine New or Archive section */ if ($reqid == 1 && $pre > time() - 604800) { $reqid = 0; $this->adminlog->create("[b]" . $this->user->getUsername() . "[/b] laddade upp [i]'" . $name . "'[/i] på Arkiv men PRE-tid säger under 7 dagar, auto-flyttar till Nytt."); } else { if ($reqid == 0 && time() - $pre > 604800) { $this->adminlog->create("[b]" . $this->user->getUsername() . "[/b] laddade upp [i]'" . $name . "'[/i] på Nytt men PRE-tid säger över 7 dagar, auto-flyttar till Arkiv."); $reqid = 1; } } } if (stripos($name, '.3d.') > -1 || stripos($name, '.hsbs.') > -1 || stripos($name, '-sbs.') > -1) { $stereoscopic = 1; } /* Presume p2p release when not rar archive */ if (in_array($category, [1, 2, 3, 4, 5, 6, 7]) && count($filelist) < 10) { $p2p = 1; } /* Block or p2p-mark non-scene groups */ $sth = $this->db->prepare("SELECT * FROM nonscene WHERE groupname = ?"); $sth->bindParam(1, $this->matchGroupName($name), PDO::PARAM_STR); $sth->execute(); $res = $sth->fetch(PDO::FETCH_ASSOC); if ($res) { if ($res["whitelist"] == 0) { throw new Exception("Release-gruppen är bannad med anledningen: " . $res["comment"], 401); } else { $p2p = 1; } } /* Torrents sized 15GB+ should be free leech */ if ($totallen > 16106127360) { $freeleech = 1; } /* Detect if torrent is a "pack" with releases inside */ $packFolders = array(); foreach ($filelist as $file) { preg_match('/^(.*?)\\//', $file[0], $match); if (strlen($match[1]) > 6) { array_push($packFolders, $match[1]); } } $packFolders = array_unique($packFolders); if (count($packFolders) > 1) { $pack = 1; } else { $pack = 0; } if ($imdbId) { $imdbInfo = $this->movieData->getData($imdbId); if ($imdbInfo["releaseNameStart"] == "") { $this->movieData->updateReleaseNameStart($name, $imdbId); } } else { $imdbInfo = $this->movieData->findImdbInfoByReleaseName($name); if ($imdbInfo) { $imdbId = $imdbInfo["id"]; } } $fname = $name . ".torrent"; $searchText = Helper::searchfield("{$name} {$imdbInfo['genres']} {$imdbInfo['imdbid']} " . implode(" ", $packFolders)); $searchText2 = Helper::searchfield("{$imdbInfo['director']} {$imdbInfo['writer']} {$imdbInfo['cast']}"); $sth = $this->db->prepare("INSERT INTO torrents (name, filename, search_text, search_text2, owner, visible, info_hash, size, numfiles, type, ano_owner, descr, category, added, last_action, frileech, tv_kanalid, tv_program, tv_episode, tv_info, imdbid, tv_klockslag, tv_programid, reqid, pre, p2p, 3d, pack, swesub) VALUES (:name, :filename, :searchText, :searchText2, :owner, 'no', :infoHash, :size, :numfiles, :type, :anoymous, :descr, :category, NOW(), NOW(), :freeLeech, :tvChannel, :tvProgram, :tvEpisode, :tvInfo, :imdbid, :tvTime, :tvProgramId, :reqid, :pre, :p2p, :3d, :pack, :swesub)"); $sth->bindParam(":name", $name, PDO::PARAM_STR); $sth->bindParam(":filename", $fname, PDO::PARAM_STR); $sth->bindParam(":searchText", $searchText, PDO::PARAM_STR); $sth->bindParam(":searchText2", $searchText2, PDO::PARAM_STR); $sth->bindParam(":owner", $this->user->getId(), PDO::PARAM_INT); $sth->bindParam(":infoHash", $infohash, PDO::PARAM_STR); $sth->bindParam(":size", $totallen, PDO::PARAM_INT); $sth->bindParam(":numfiles", count($filelist), PDO::PARAM_INT); $sth->bindParam(":type", $type, PDO::PARAM_STR); $sth->bindParam(":anoymous", $anonymousUpload, PDO::PARAM_INT); $sth->bindParam(":descr", $nfo, PDO::PARAM_STR); $sth->bindParam(":category", $category, PDO::PARAM_INT); $sth->bindParam(":freeLeech", $freeleech, PDO::PARAM_INT); $sth->bindParam(":tvChannel", $tvChannel, PDO::PARAM_INT); $sth->bindParam(":tvProgram", $tvProgram, PDO::PARAM_STR); $sth->bindParam(":tvEpisode", $tvEpisode, PDO::PARAM_STR); $sth->bindParam(":tvInfo", $tvInfo, PDO::PARAM_STR); $sth->bindParam(":tvTime", $tvTime, PDO::PARAM_INT); $sth->bindParam(":tvProgramId", $tvProgramId, PDO::PARAM_INT); $sth->bindParam(":imdbid", $imdbId, PDO::PARAM_INT); $sth->bindParam(":reqid", $reqid, PDO::PARAM_INT); $sth->bindParam(":pre", $pre, PDO::PARAM_INT); $sth->bindParam(":p2p", $p2p, PDO::PARAM_INT); $sth->bindParam(":3d", $stereoscopic, PDO::PARAM_INT); $sth->bindParam(":pack", $pack, PDO::PARAM_INT); $sth->bindParam(":swesub", $swesub, PDO::PARAM_INT); $sth->execute(); $insertId = $this->db->lastInsertId(); $sth = $this->db->prepare("INSERT INTO files (torrent, filename, size) VALUES (?, ?, ?)"); foreach ($filelist as $file) { $sth->bindParam(1, $insertId, PDO::PARAM_INT); $sth->bindParam(2, $file[0], PDO::PARAM_STR); $sth->bindParam(3, $file[1], PDO::PARAM_INT); $sth->execute(); } if (count($packFolders) > 1) { $sth = $this->db->prepare("INSERT INTO packfiles(torrent, filename) VALUES (?, ?)"); foreach ($packFolders as $folder) { $sth->bindParam(1, $insertId, PDO::PARAM_INT); $sth->bindParam(2, $folder, PDO::PARAM_STR); $sth->execute(); } } move_uploaded_file($uploaded_file["tmp_name"], $this->torrentDir . $insertId . ".torrent"); $fp = fopen($this->torrentDir . $insertId . ".torrent", "w"); if ($fp) { @fwrite($fp, benc($dict), strlen(benc($dict))); fclose($fp); } $this->user->initTorrentComments(); if ($reqid > 2) { $this->requests->fill($reqid); $votes = $this->requests->getVotes($reqid); $uploader = "[url=/user/" . $this->user->getId() . "/" . $this->user->getUsername() . "][b]" . $this->user->getUsername() . "[/b][/url]"; if ($anonymousUpload) { $uploader = "[i]Anonym[/i]"; } $message = "Requesten [url=/torrent/" . $insertId . "/" . $name . "][b]" . $name . "[/b][/url] har blivit uppladdad av " . $uploader; foreach ($votes as $vote) { if ($vote["user"]["id"] !== $this->user->getId()) { $this->mailbox->sendSystemMessage($vote["user"]["id"], "Request uppladdad!", $message); } } } $this->log->log(1, "Torrent ([url=/torrent/" . $insertId . "/" . $name . "][b]" . $name . "[/b][/url]) laddades upp utav {{username}}", $this->user->getId(), $anonymousUpload); /* Flush memcached */ if ($memcache) { if ($category == 8) { $memcache->delete('swetvguide-0'); } } /* Give uploaders more free leech when uploading torrent */ if ($reqid == 0 && $p2p == 0 && $pack == 0) { $leechStart = strtotime($this->user->getLeechStart()); $newLeech = round($totallen / 1024 / 1024 * 0.02); if ($leechStart > time()) { $newLeech = $leechStart + $newLeech * 100; } else { $newLeech = time() + $newLeech * 100; } $this->db->query("UPDATE users SET leechstart = FROM_UNIXTIME(" . $newLeech . ") WHERE id = " . $this->user->getId()); } return array("id" => $insertId, "name" => $name); }
public function upload($uploaded_file, $post) { if ($this->user->isUploadBanned()) { throw new Exception(L::get("TORRENT_UPLOAD_BANNED"), 401); } $max_torrent_size = 10000000; ini_set("upload_max_filesize", $max_torrent_size); include 'benc.php'; if ($post["category"] < Config::$categories["DVDR_PAL"]["id"] || $post["category"] > Config::$categories["MOVIE_4K"]["id"]) { throw new Exception(L::get("TORRENT_INVALID_CATEGORY")); } if ($post["section"] !== 'new' && $post["section"] !== 'archive') { throw new Exception(L::get("TORRENT_INVALID_SECTION")); } if (!preg_match("/\\.torrent\$/", $uploaded_file["name"], $match)) { throw new Exception(L::get("TORRENT_INVLID_FILE")); } if (!is_uploaded_file($uploaded_file["tmp_name"])) { throw new Exception(L::get("TORRENT_UPLOAD_ERROR")); } if (!filesize($uploaded_file["tmp_name"])) { throw new Exception(L::get("TORRENT_EMPTY_FILE_ERROR")); } if ($post["category"] == Config::$categories["TV_SWE"]["id"] && $post["section"] == 'new' && ($post["channel"] == 0 || $post["program"] == 0)) { throw new Exception(L::get("TORRENT_SWE_TV_DATA_MISSING"), 412); } if ($post["reqid"] > 0) { $request = $this->requests->get($post["reqid"]); if ($this->user->getId() == $request["user"]["id"]) { throw new Exception(L::get("TORRENT_FILL_OWN_REQUEST_ERROR"), 400); } if ($request["filled"] == 1) { throw new Exception(L::get("TORRENT_REQUEST_ALREADY_FILLED_ERROR"), 400); } } $name = preg_replace("/\\.torrent\$/", '', $uploaded_file["name"]); $category = $post["category"]; $section = $post["section"]; $reqid = $post["reqid"]; $anonymousUpload = $post["anonymousUpload"]; $nfo = $post["nfo"]; $imdbId = $post["imdbId"]; $p2p = $post["p2p"]; $freeleech = 0; $sweaudio = $post["sweaudio"] ?: 0; $stereoscopic = 0; $swesub = 0; /* The following categories should always be tagged with "has swesub" */ if (in_array($category, array(Config::$categories["DVDR_PAL"]["id"], Config::$categories["DVDR_CUSTOM"]["id"], Config::$categories["DVDR_TV"]["id"], Config::$categories["EBOOKS"]["id"], Config::$categories["EPAPERS"]["id"], Config::$categories["BLURAY"]["id"], Config::$categories["SUBPACK"]["id"]))) { $swesub = 2; } /* The following categories should be marked with "has swesub" if release "contains" swesub */ if ($post["swesub"] == 1 && in_array($category, array(Config::$categories["MOVIE_720P"]["id"], Config::$categories["MOVIE_1080P"]["id"], Config::$categories["TV_720P"]["id"], Config::$categories["TV_1080P"]["id"], Config::$categories["MOVIE_4K"]["id"]))) { $swesub = 2; } /* SWE TV is excepted from swe audio tag */ if ($post["sweaudio"] && in_array($category, array(Config::$categories["TV_SWE"]["id"], Config::$categories["AUDIOBOOKS"]["id"], Config::$categories["EBOOKS"]["id"], Config::$categories["EPAPERS"]["id"], Config::$categories["MUSIC"]["id"], Config::$categories["SUBPACK"]["id"]))) { $sweaudio = 0; } /* SWE-TV */ $tvProgramId = $post["program"] ?: 0; $tvChannel = $post["channel"] ?: 0; $tvProgram = ''; $tvEpisode = ''; $tvInfo = ''; $tvTime = 0; if ($category == Config::$categories["TV_SWE"]["id"] && $tvProgramId > 0 && $tvChannel > 0) { /* Manual entered program */ if ($tvProgramId == 1) { $tvProgram = $post["programTitle"]; $tvTime = strtotime($post["programDate"]); if (strlen($tvProgram) < 2) { throw new Exception(L::get("TORRENT_TV_NAME_TOO_SHORT")); } $tvProgramId = 2; } else { $sweTv = $this->sweTv->getProgram($tvProgramId); if (!$sweTv) { throw new Exception(L::get("TORRENT_TV_PROGRAM_INVALID")); } $tvProgram = $sweTv["program"]; $tvEpisode = $sweTv["episod"]; $tvInfo = $sweTv["info"]; $tvTime = $sweTv["datum"]; } } if ($this->user->getClass() < User::CLASS_UPLOADER && $section == 'new') { throw new Exception(L::get("TORRENT_UPLOADER_REQUIRED_NEW")); } $sth = $this->db->prepare("SELECT COUNT(*) FROM torrents WHERE name = ?"); $sth->execute(array($name)); $arr = $sth->fetch(); if ($arr[0] == 1) { throw new Exception(L::get("TORRENT_CONFLICT"), 409); } $sth = $this->db->prepare("SELECT COUNT(*) FROM packfiles WHERE filename = ?"); $sth->execute(array($name)); $arr = $sth->fetch(); if ($arr[0] == 1) { throw new Exception(L::get("TORRENT_CONFLICT_IN_PACK"), 409); } $sth = $this->db->prepare("SELECT comment FROM banned WHERE namn = ?"); $sth->execute(array($name)); while ($arr = $sth->fetch(PDO::FETCH_ASSOC)) { throw new Exception(L::get("TORRENT_BANNED", [$arr["comment"]])); } $dict = bdec_file($uploaded_file["tmp_name"], $max_torrent_size); if (!isset($dict)) { throw new Exception(L::get("TORRENT_FILE_ERROR")); } function dict_check($d, $s) { if ($d["type"] != "dictionary") { throw new Exception(L::get("TORRENT_INVLID_FILE")); } $a = explode(":", $s); $dd = $d["value"]; $ret = array(); foreach ($a as $k) { unset($t); if (preg_match('/^(.*)\\((.*)\\)$/', $k, $m)) { $k = $m[1]; $t = $m[2]; } if (isset($t)) { if ($dd[$k]["type"] != $t) { throw new Exception(L::get("TORRENT_MISSING_ANNOUNCE_URL")); } $ret[] = $dd[$k]["value"]; } else { $ret[] = $dd[$k]; } } return $ret; } function dict_get($d, $k, $t) { if ($d["type"] != "dictionary") { throw new Exception(L::get("TORRENT_FILE_ERROR")); } $dd = $d["value"]; if (!isset($dd[$k])) { return; } $v = $dd[$k]; if ($v["type"] != $t) { throw new Exception(L::get("TORRENT_FILE_ERROR")); } return $v["value"]; } list($ann, $info) = dict_check($dict, "announce(string):info"); list($dname, $plen, $pieces) = dict_check($info, "name(string):piece length(integer):pieces(string)"); if (strlen($pieces) % 20 != 0) { throw new Exception(L::get("TORRENT_FILE_ERROR")); } $filelist = array(); $totallen = dict_get($info, "length", "integer"); if (isset($totallen)) { $filelist[] = array($dname, $totallen); $type = "single"; } else { $flist = dict_get($info, "files", "list"); if (!isset($flist)) { throw new Exception(L::get("TORRENT_MISSSING_FILES_LENGTH")); } if (!count($flist)) { throw new Exception(L::get("TORRENT_MISSING_FILES")); } $totallen = 0; foreach ($flist as $fn) { list($ll, $ff) = dict_check($fn, "length(integer):path(list)"); $totallen += $ll; $ffa = array(); foreach ($ff as $ffe) { if ($ffe["type"] != "string") { throw new Exception(L::get("TORRENT_FILE_NAME_ERROR")); } $ffa[] = $ffe["value"]; } if (!count($ffa)) { throw new Exception(L::get("TORRENT_FILE_NAME_ERROR")); } $ffe = implode("/", $ffa); $filelist[] = array($ffe, $ll); } $type = "multi"; } $foundBanned = array(); $bannedfiles = array(".DS_Store", "._.DS_Store", "ufxpcrc.log", "Thumbs.db", ".checked", ".message", "desktop.ini", "Default.PLS", ".url", ".html", "imdb.nfo", ".missing", "-missing", ".torrent"); foreach ($filelist as $file) { foreach ($bannedfiles as $bfile) { if (preg_match("/" . $bfile . "\$/", $file[0])) { $foundBanned[] = $file[0]; } } } if (count($foundBanned) > 0) { $files = ''; foreach ($foundBanned as $f) { $files .= '\'' . $f . '\', '; } $this->adminlog->create(L::get("TORRENT_CONTAINING_BANNED_FILES_LOG", [$this->user->getUsername(), $name, $files], Config::DEFAULT_LANGUAGE)); throw new Exception(L::get("TORRENT_CONTAINING_BANNED_FILES", [$files])); } if (($txt = $this->detectMissingFiles($filelist)) != false) { $this->adminlog->create(L::get("TORRENT_PREVENTED_BANNED_FILE", [$this->user->getUsername(), $name], Config::DEFAULT_LANGUAGE) . $txt); throw new Exception(L::get("TORRENT_MISSING_FOLLOWING_FILES") . $txt); } $info['value']['source']['type'] = "string"; $info['value']['source']['value'] = Config::SITE_NAME; $info['value']['source']['strlen'] = strlen($info['value']['source']['value']); $info['value']['private']['type'] = "integer"; $info['value']['private']['value'] = 1; $dict['value']['info'] = $info; $dict = benc($dict); $dict = bdec($dict); list($ann, $info) = dict_check($dict, "announce(string):info"); $infohash = bin2hex(pack("H*", sha1($info["string"]))); $sth = $this->db->prepare("SELECT COUNT(*) FROM torrents WHERE info_hash = ?"); $sth->bindParam(1, $infohash, PDO::PARAM_STR); $sth->execute(); $arr = $sth->fetch(); if ($arr[0] == 1) { throw new Exception(L::get("TORRENT_CONFLICT"), 409); } $pre = Helper::preCheck($name); if (!$pre) { $pre = 0; } else { if ($pre > time()) { $pre = time() - 100; } /* Use pre-time to determine New or Archive section */ if ($section == 'archive' && $pre > time() - 604800) { $section = 'new'; $this->adminlog->create(L::get("TORRENT_AUTO_MOVED_NEW", [$this->user->getUsername(), $name], Config::DEFAULT_LANGUAGE)); } else { if ($section == 'new' && time() - $pre > 604800) { $this->adminlog->create(L::get("TORRENT_AUTO_MOVED_ARCHIVE", [$this->user->getUsername(), $name], Config::DEFAULT_LANGUAGE)); $section = 'archive'; } } } if (stripos($name, '.3d.') > -1 || stripos($name, '.hsbs.') > -1 || stripos($name, '-sbs.') > -1) { $stereoscopic = 1; } /* Presume p2p release when not rar archive */ if (in_array($category, [Config::$categories["DVDR_PAL"]["id"], Config::$categories["DVDR_CUSTOM"]["id"], Config::$categories["DVDR_TV"]["id"], Config::$categories["MOVIE_720P"]["id"], Config::$categories["MOVIE_1080P"]["id"], Config::$categories["TV_720P"]["id"], Config::$categories["TV_1080P"]["id"], Config::$categories["BLURAY"]["id"], Config::$categories["MOVIE_4K"]["id"]]) && count($filelist) < 10) { $p2p = 1; } /* Block or p2p-mark non-scene groups */ $sth = $this->db->prepare("SELECT * FROM nonscene WHERE groupname = ?"); $sth->bindValue(1, $this->matchGroupName($name), PDO::PARAM_STR); $sth->execute(); $res = $sth->fetch(PDO::FETCH_ASSOC); if ($res) { if ($res["whitelist"] == 0) { throw new Exception(L::get("TORRENT_RELEASE_GROUP_BANNED", [$res["comment"]]), 401); } else { $p2p = 1; } } /* Torrents sized 15GB+ should be free leech */ if ($totallen > 16106127360 && $category != Config::$categories["BLURAY"]["id"] && $category != Config::$categories["MOVIE_4K"]["id"]) { $freeleech = 1; } /* Detect if torrent is a "pack" with releases inside */ $packFolders = array(); foreach ($filelist as $file) { preg_match('/^(.*?)\\//', $file[0], $match); if (strlen($match[1]) > 6) { array_push($packFolders, $match[1]); } } $packFolders = array_unique($packFolders); if (count($packFolders) > 1) { $pack = 1; } else { $pack = 0; } if ($imdbId) { $imdbInfo = $this->movieData->getData($imdbId); /* Always replace the release name start when empty or tv-show to keep it up to date for auto-matching */ if ($imdbInfo["releaseNameStart"] == "" || in_array($category, [Config::$categories["TV_720P"]["id"], Config::$categories["TV_1080P"]["id"]])) { $this->movieData->updateReleaseNameStart($name, $imdbId); } } $fname = $name . ".torrent"; $searchText = Helper::searchfield("{$name} {$imdbInfo['genres']} {$imdbInfo['imdbid']} " . implode(" ", $packFolders)); $searchText2 = Helper::searchfield("{$imdbInfo['director']} {$imdbInfo['writer']} {$imdbInfo['cast']}"); $sth = $this->db->prepare("INSERT INTO torrents (name, filename, search_text, search_text2, owner, visible, info_hash, size, numfiles, type, ano_owner, descr, category, added, last_action, frileech, tv_kanalid, tv_program, tv_episode, tv_info, imdbid, tv_klockslag, tv_programid, reqid, section, pre, p2p, 3d, pack, swesub, sweaudio) VALUES (:name, :filename, :searchText, :searchText2, :owner, 'no', :infoHash, :size, :numfiles, :type, :anoymous, :descr, :category, NOW(), NOW(), :freeLeech, :tvChannel, :tvProgram, :tvEpisode, :tvInfo, :imdbid, :tvTime, :tvProgramId, :reqid, :section, :pre, :p2p, :3d, :pack, :swesub, :sweaudio)"); $sth->bindParam(":name", $name, PDO::PARAM_STR); $sth->bindParam(":filename", $fname, PDO::PARAM_STR); $sth->bindParam(":searchText", $searchText, PDO::PARAM_STR); $sth->bindParam(":searchText2", $searchText2, PDO::PARAM_STR); $sth->bindValue(":owner", $this->user->getId(), PDO::PARAM_INT); $sth->bindParam(":infoHash", $infohash, PDO::PARAM_STR); $sth->bindParam(":size", $totallen, PDO::PARAM_INT); $sth->bindValue(":numfiles", count($filelist), PDO::PARAM_INT); $sth->bindParam(":type", $type, PDO::PARAM_STR); $sth->bindParam(":anoymous", $anonymousUpload, PDO::PARAM_INT); $sth->bindParam(":descr", $nfo, PDO::PARAM_STR); $sth->bindParam(":category", $category, PDO::PARAM_INT); $sth->bindParam(":freeLeech", $freeleech, PDO::PARAM_INT); $sth->bindParam(":tvChannel", $tvChannel, PDO::PARAM_INT); $sth->bindParam(":tvProgram", $tvProgram, PDO::PARAM_STR); $sth->bindParam(":tvEpisode", $tvEpisode, PDO::PARAM_STR); $sth->bindParam(":tvInfo", $tvInfo, PDO::PARAM_STR); $sth->bindParam(":tvTime", $tvTime, PDO::PARAM_INT); $sth->bindParam(":tvProgramId", $tvProgramId, PDO::PARAM_INT); $sth->bindParam(":imdbid", $imdbId, PDO::PARAM_INT); $sth->bindParam(":reqid", $reqid, PDO::PARAM_INT); $sth->bindParam(":section", $section, PDO::PARAM_STR); $sth->bindParam(":pre", $pre, PDO::PARAM_INT); $sth->bindParam(":p2p", $p2p, PDO::PARAM_INT); $sth->bindParam(":3d", $stereoscopic, PDO::PARAM_INT); $sth->bindParam(":pack", $pack, PDO::PARAM_INT); $sth->bindParam(":swesub", $swesub, PDO::PARAM_INT); $sth->bindParam(":sweaudio", $sweaudio, PDO::PARAM_INT); $sth->execute(); $insertId = $this->db->lastInsertId(); $sth = $this->db->prepare("INSERT INTO files (torrent, filename, size) VALUES (?, ?, ?)"); foreach ($filelist as $file) { $sth->bindParam(1, $insertId, PDO::PARAM_INT); $sth->bindParam(2, $file[0], PDO::PARAM_STR); $sth->bindParam(3, $file[1], PDO::PARAM_INT); $sth->execute(); } if (count($packFolders) > 1) { $sth = $this->db->prepare("INSERT INTO packfiles(torrent, filename) VALUES (?, ?)"); foreach ($packFolders as $folder) { $sth->bindParam(1, $insertId, PDO::PARAM_INT); $sth->bindParam(2, $folder, PDO::PARAM_STR); $sth->execute(); } } move_uploaded_file($uploaded_file["tmp_name"], $this->torrentDir . $insertId . ".torrent"); $fp = fopen($this->torrentDir . $insertId . ".torrent", "w"); if ($fp) { @fwrite($fp, benc($dict), strlen(benc($dict))); fclose($fp); } $this->user->initTorrentComments(); if ($reqid > 0) { $this->requests->fill($reqid); $votes = $this->requests->getVotes($reqid); $uploader = "[url=/user/" . $this->user->getId() . "/" . $this->user->getUsername() . "][b]" . $this->user->getUsername() . "[/b][/url]"; foreach ($votes as $vote) { if ($anonymousUpload) { $uploader = "[i]" . L::get("TORRENT_ANONYMOUS", null, $vote["user"]["language"]) . "[/i]"; } $message = L::get("TORRENT_REQUEST_FILLED_PM_BODY", [$insertId, $name, $name, $uploader], $vote["user"]["language"]); if ($vote["user"]["id"] !== $this->user->getId()) { $this->mailbox->sendSystemMessage($vote["user"]["id"], L::get("TORRENT_REQUEST_FILLED_PM_TOPIC", null, $vote["user"]["language"]), $message); } } } $this->log->log(1, L::get("TORRENT_UPLOADED_LOG", [$insertId, $name, $name], Config::DEFAULT_LANGUAGE), $this->user->getId(), $anonymousUpload); /* Flush memcached */ if ($memcached && $category == 8) { $memcached->delete('swetvguide-0'); $memcached->delete('swetvguide-1'); $memcached->delete('swetvguide-2'); } /* Give uploaders more free leech when uploading torrent */ if ($section == 'new' && $p2p == 0 && $pack == 0) { $leechStart = strtotime($this->user->getLeechStart()); $newLeech = round($totallen / 1024 / 1024 * 0.02); if ($leechStart > time()) { $newLeech = $leechStart + $newLeech * 100; } else { $newLeech = time() + $newLeech * 100; } $this->db->query("UPDATE users SET leechstart = FROM_UNIXTIME(" . $newLeech . ") WHERE id = " . $this->user->getId()); } return array("id" => $insertId, "name" => $name); }
function bdec_list($s) { if ($s[0] != 'l') { return; } $sl = strlen($s); $i = 1; $v = array(); $ss = 'l'; for (;;) { if ($i >= $sl) { return; } if ($s[$i] == 'e') { break; } $ret = bdec(substr($s, $i)); if (!isset($ret) || !is_array($ret)) { return; } $v[] = $ret; $i += $ret['strlen']; $ss .= $ret['string']; } $ss .= 'e'; return array(type => 'list', value => $v, strlen => strlen($ss), string => $ss); }
function doubleUp() { $this->_dict = bdec(benc($this->_dict)); }
$v = $dd[$k]; if ($v["type"] != $t) bark("ógild tegund orðabókarfærslu"); return $v["value"]; } // This section creates the additonal dictionary entries $dict["value"]["info"]["value"]["private"]["type"] = "integer"; $dict["value"]["info"]["value"]["private"]["value"] = 1; $dict["value"]["info"]["value"]["source"]["type"] = "string"; $dict["value"]["info"]["value"]["source"]["value"] = "Istorrent"; $dict["value"]["info"]["value"]["source"]["strlen"] = strlen($dict["value"]["info"]["value"]["source"]["value"]); // This bencodes and bdecodes again - necessary... $fn = benc($dict); $dict = bdec($fn); list($ann, $info) = dict_check($dict, "announce(string):info"); list($dname, $plen, $pieces) = dict_check($info, "name(string):piece length(integer):pieces(string)"); if (!in_array($ann, $announce_urls, 1)) bark("Lokað er á torrent frá öðrum síðum, búið til ný torrent með tilkynningarslóðinni " . $announce_urls[0] . ". Tilkynningarslóðin sem stendur í torrent skránni sem þú sendir er " . $ann . "."); if (strlen($pieces) % 20 != 0) bark("invalid pieces"); $filelist = array(); $totallen = dict_get($info, "length", "integer"); if (isset($totallen)) { $filelist[] = array($dname, $totallen);