"); if ($PRINT_DEBUG) print("[ Script Execution time: ".number_format(($time_end-$time_start),4)." sec. ] - [ GZIP: $gzip ]
"); print("BtitTracker (1.3.1) by Btiteam

"); } ////////////////////////////////////////////////////////////////// // Worker functions if (function_exists("bcadd")) { function sqlAdd($left, $right) { return bcadd($left, $right,0); } function sqlSubtract($left, $right) { return bcsub($left, $right,0); } function sqlMultiply($left, $right) { return bcmul($left, $right,0); } function sqlDivide($left, $right) { return bcdiv($left, $right,0); } } else // BC vs SQL math { // Uses the mysql database connection to perform string math. :) // Used by byte counting functions // No error handling as we assume nothing can go wrong. :| function sqlAdd($left, $right) { $query = 'SELECT '.$left.'+'.$right; $results = mysql_query($query) or showError(DATABASE_ERROR); return mysql_result($results,0,0); } // Ditto function sqlSubtract($left, $right) { $query = 'SELECT '.$left.'-'.$right; $results = mysql_query($query) or showError(DATABASE_ERROR); return mysql_result($results,0,0); } function sqlDivide($left, $right) { $query = 'SELECT '.$left.'/'.$right; $results = mysql_query($query) or showError(DATABASE_ERROR); return mysql_result($results,0,0); } function sqlMultiply($left, $right) { $query = 'SELECT '.$left.'*'.$right; $results = mysql_query($query) or showError(DATABASE_ERROR); return mysql_result($results,0,0); } } // End of BC vs SQL // Runs a query with no regard for the result function quickQuery($query) { $results = @mysql_query($query); if (!is_bool($results)) mysql_free_result($results); else return $results; return true; } function hex2bin ($input, $assume_safe=true) { if ($assume_safe !== true && ! ((strlen($input) % 2) === 0 || preg_match ('/^[0-9a-f]+$/i', $input))) return ""; return pack('H*', $input ); } // Reports an error to the client in $message. // Any other output will confuse the client, so please don't do that. function showError($message, $log=false) { if ($log) error_log("BtiTracker: ".SENT_ERROR." ($message)"); echo "d14:failure reason".strlen($message).":$message"."e"; exit(0); } // Used by newtorrents.php and the dynamic_torrents setting // Returns true/false, depending on if there were errors. function makeTorrent($hash, $tolerate = false) { if (strlen($hash) != 40) showError(MKTOR_INVALID_HASH); $result = true; // new with domain suffix and client //$query = "CREATE TABLE x$hash (peer_id char(40) NOT NULL default '', bytes bigint NOT NULL default 0, ip char(50) NOT NULL default 'error.x', port smallint UNSIGNED NOT NULL default \"0\", status enum('leecher','seeder') NOT NULL, lastupdate int unsigned NOT NULL default 0, sequence int unsigned AUTO_INCREMENT NOT NULL, natuser enum('N', 'Y') not null default 'N', client varchar(60) NOT NULL default '', dns varchar(100) NOT NULL default '', uploaded bigint(20) unsigned not null default '0', downloaded bigint(20) unsigned not null default '0', pid char(32) null, primary key(sequence), unique(peer_id))"; //if (!@mysql_query($query)) // $result = false; if (!$result && !$tolerate) return false; if (isset($GLOBALS["peercaching"]) && $GLOBALS["peercaching"]) { //$query = "CREATE TABLE y$hash (sequence int unsigned NOT NULL default 0, with_peerid char(101) NOT NULL default '', without_peerid char(40) NOT NULL default '', compact char(6) NOT NULL DEFAULT '', unique k (sequence)) DELAY_KEY_WRITE=1 CHECKSUM=0"; //mysql_query($query); } $query = "INSERT INTO summary set info_hash=\"".$hash."\", lastSpeedCycle=UNIX_TIMESTAMP()"; if (!@mysql_query($query)) $result = false; return $result; } // Returns true if the torrent exists. // Currently checks by locating the row in "summary" // Always returns true if $dynamic_torrents=="1" unless an error occured function verifyTorrent($hash) { // only for internal tracked torrent! $query = "SELECT COUNT(*) FROM summary INNER JOIN namemap ON namemap.info_hash=summary.info_hash WHERE namemap.external='no' AND summary.info_hash=\"$hash\""; $results = mysql_query($query); $res = mysql_result($results,0,0); if ($res == 1) return true; if ($GLOBALS["dynamic_torrents"]) return makeTorrent($hash); return false; } function verifyHash($input) { if (strlen($input) === 40 && preg_match('/^[0-9a-f]+$/', $input)) return true; else return false; } // Returns info on one peer function getPeerInfo($user, $hash) { // If "trackerid" is set, let's try that if (isset($GLOBALS["trackerid"])) { $query = "SELECT peer_id,bytes,ip,port,status,lastupdate,sequence FROM peers WHERE sequence=${GLOBALS["trackerid"]} AND infohash=\"$hash\""; $results = mysql_query($query) or showError("Tracker error: invalid torrent"); $data = mysql_fetch_assoc($results); if (!$data || $data["peer_id"] != $user) { // Damn, but don't crash just yet. $query = "SELECT peer_id,bytes,ip,port,status,lastupdate,sequence from peers where peer_id=\"$user\" AND infohash=\"$hash\""; $results = mysql_query($query) or showError(INVALID_TORRENT); $data = mysql_fetch_assoc($results); $GLOBALS["trackerid"] = $data["sequence"]; } } else { $query = "SELECT peer_id,bytes,ip,port,status,lastupdate,sequence from peers where peer_id=\"$user\" AND infohash=\"$hash\""; $results = mysql_query($query) or showError(INVALID_TORRENT); $data = mysql_fetch_assoc($results); $GLOBALS["trackerid"] = $data["sequence"]; } if (!($data)) return false; return $data; } // Slight redesign of loadPeers function getRandomPeers($hash, $where="") { // Don't want to send a bad "num peers" for new seeds $where="WHERE infohash=\"$hash\""; if ($GLOBALS["NAT"]) $results = mysql_query("SELECT COUNT(*) FROM peers WHERE natuser = 'N' AND infohash=\"$hash\""); else $results = mysql_query("SELECT COUNT(*) FROM peers WHERE infohash=\"$hash\""); $peercount = mysql_result($results, 0,0); // ORDER BY RAND() is expensive. Don't do it when the load gets too high if ($peercount < 500) $query = "SELECT ".((isset($_GET["no_peer_id"]) && $_GET["no_peer_id"] == 1) ? "" : "peer_id,")."ip, port, status FROM peers ".$where." ORDER BY RAND() LIMIT ${GLOBALS['maxpeers']}"; else $query = "SELECT ".((isset($_GET["no_peer_id"]) && $_GET["no_peer_id"] == 1) ? "" : "peer_id,")."ip, port, status FROM peers ".$where." LIMIT ".@mt_rand(0, $peercount - $GLOBALS["maxpeers"]).", ${GLOBALS['maxpeers']}"; $results = mysql_query($query); if (!$results) return false; $peerno = 0; while ($return[] = mysql_fetch_assoc($results)) $peerno++; array_pop ($return); mysql_free_result($results); $return['size'] = $peerno; return $return; } // Deletes a peer from the system and performs all cleaning up // // $assumepeer contains the result of getPeerInfo, or false // if we should grab it ourselves. function killPeer($userid, $hash, $left, $assumepeer = false) { if (!$assumepeer) { $peer = getPeerInfo($userid, $hash); if (!$peer) return; if ($left != $peer["bytes"]) $bytes = sqlSubtract($peer["bytes"], $left); else $bytes = 0; } else { $bytes = 0; $peer = $assumepeer; } quickQuery("DELETE FROM peers WHERE peer_id=\"$userid\" AND infohash=\"$hash\""); if (mysql_affected_rows() == 1) { // if ($GLOBALS["peercaching"]) // quickQuery("DELETE FROM y$hash WHERE sequence=" . $peer["sequence"]); if ($peer["status"] == "leecher") summaryAdd("leechers", -1); else summaryAdd("seeds", -1); if ($GLOBALS["countbytes"] && ((float)$bytes) > 0) summaryAdd("dlbytes",$bytes); if ($peer["bytes"] != 0 && $left == 0) summaryAdd("finished", 1); } } // Updates the peer user's info. // Currently it does absolutely nothing. lastupdate is set in collectBytes // as well. function updatePeer($peerid, $hash) { } // Transfers bytes from "left" to "dlbytes" when a peer reports in. function collectBytes($peer, $hash, $left, $downloaded=0, $uploaded=0, $pid="") { $peerid=$peer["peer_id"]; if (!$GLOBALS["countbytes"]) { quickQuery("UPDATE peers SET lastupdate=UNIX_TIMESTAMP(), downloaded=$downloaded, uploaded=$uploaded, pid=\"$pid\" where infohash=\"$hash\" AND " . (isset($GLOBALS["trackerid"]) ? "sequence=\"${GLOBALS["trackerid"]}\"" : "peer_id=\"$peerid\"")); return; } $diff = sqlSubtract($peer["bytes"], $left); quickQuery("UPDATE peers set " . (($diff != 0) ? "bytes=\"$left\"," : ""). " lastupdate=UNIX_TIMESTAMP(), downloaded=$downloaded, uploaded=$uploaded, pid=\"$pid\" where infohash=\"$hash\" AND " . (isset($GLOBALS["trackerid"]) ? "sequence=\"${GLOBALS["trackerid"]}\"" : "peer_id=\"$peerid\"")); // Anti-negative clause if (((float)$diff) > 0) summaryAdd("dlbytes", $diff); } // Transmits the actual data to the peer. No other output is permitted if // this function is called, as that would break BEncoding. // I don't use the bencode library, so watch out! If you add data, // rules such as dictionary sorting are enforced by the remote side. function sendPeerList($peers) { echo "d"; echo "8:intervali".$GLOBALS["report_interval"]."e"; if (isset($GLOBALS["min_interval"])) echo "12:min intervali".$GLOBALS["min_interval"]."e"; echo "5:peers"; $size=$peers["size"]; if (isset($_GET["compact"]) && $_GET["compact"] == '1') { $p = ''; for ($i=0; $i < $size; $i++) $p .= str_pad(pack("Nn", ip2long($peers[$i]['ip']), $peers[$i]['port']), 6); echo strlen($p).':'.$p; } else // no_peer_id or no feature supported { echo 'l'; for ($i=0; $i < $size; $i++) { echo "d2:ip".strlen($peers[$i]["ip"]).":".$peers[$i]["ip"]; if (isset($peers[$i]["peer_id"])) echo "7:peer id20:".hex2bin($peers[$i]["peer_id"]); echo "4:port".$peers[$i]["port"]."ee"; } echo "e"; } if (isset($GLOBALS["trackerid"])) { // Now it gets annoying. trackerid is a string echo "10:tracker id".strlen($GLOBALS["trackerid"]).":".$GLOBALS["trackerid"]; } echo "e"; } // Faster pass-through version of getRandompeers => sendPeerList // It's the only way to use cache tables. In fact, it only uses it. function sendRandomPeers($info_hash) { $result = mysql_query("SELECT COUNT(*) FROM peers WHERE infohash=\"$info_hash\""); $count = mysql_result($result, 0, 0); if (isset($_GET["compact"]) && $_GET["compact"] == '1') $column = "compact"; else if (isset($_GET["no_peer_id"]) && $_GET["no_peer_id"] == '1') $column = "without_peerid"; else $column = "with_peerid"; if ($count < $GLOBALS["maxpeers"]) $query = "SELECT $column FROM peers WHERE infohash=\"$info_hash\""; else if ($count > 500) { do { $rand1 = mt_rand(0, $count-$GLOBALS["maxpeers"]); $rand2 = mt_rand(0, $count-$GLOBALS["maxpeers"]); } while (abs($rand1 - $rand2) < $GLOBALS["maxpeers"]/2); $query = "(SELECT $column FROM peers WHERE infohash=\"$info_hash\" LIMIT $rand1, ".($GLOBALS["maxpeers"]/2). ") UNION (SELECT $column FROM peers WHERE infohash=\"$info_hash\" LIMIT $rand2, ".($GLOBALS["maxpeers"]/2). ")"; } else $query = "SELECT $column FROM peers WHERE infohash=\"$info_hash\" ORDER BY RAND() LIMIT ".$GLOBALS["maxpeers"]; echo "d"; echo "8:intervali".$GLOBALS["report_interval"]."e"; if (isset($GLOBALS["min_interval"])) echo "12:min intervali".$GLOBALS["min_interval"]."e"; echo "5:peers"; $result = mysql_query($query); if ($column == "compact") { echo (mysql_num_rows($result) * 6) . ":"; while ($row = mysql_fetch_row($result)) echo str_pad($row[0], 6); //echo $row[0]; } else { echo "l"; while ($row = mysql_fetch_row($result)) echo "d".$row[0]."e"; echo "e"; } if (isset($GLOBALS["trackerid"])) echo "10:tracker id".strlen($GLOBALS["trackerid"]).":".$GLOBALS["trackerid"]; echo "e"; } // Returns a $peers array of all peers that have timed out (2* report interval seems fair // for any reasonable report interval (900 or larger)) function loadLostPeers($hash, $timeout) { $results = mysql_query("SELECT peer_id,bytes,ip,port,status,lastupdate,sequence from peers WHERE infohash=\"$hash\" AND lastupdate < (UNIX_TIMESTAMP() - 2 * $timeout)"); //echo "SELECT peer_id,bytes,ip,port,status,lastupdate,sequence from x$hash WHERE infohash=\"$hash\" AND lastupdate < (UNIX_TIMESTAMP() - 2 * $timeout)
"; $peerno = 0; if (!$results) return false; while ($return[] = mysql_fetch_assoc($results)) $peerno++; array_pop($return); $return["size"] = $peerno; mysql_free_result($results); return $return; } function trashCollector($hash, $timeout) { if (isset($GLOBALS["trackerid"])) unset($GLOBALS["trackerid"]); if (!Lock($hash)) return; $results = mysql_query("SELECT lastcycle FROM summary WHERE info_hash='$hash'"); $lastcheck = (mysql_fetch_row($results)); // Check once every re-announce cycle if (($lastcheck[0] + $timeout) < time()) { $peers = loadLostPeers($hash, $timeout); for ($i=0; $i < $peers["size"]; $i++) killPeer($peers[$i]["peer_id"], $hash, $peers[$i]["bytes"]); summaryAdd("lastcycle", "UNIX_TIMESTAMP()", true); } Unlock($hash); } // Attempts to aquire a lock by name. // Returns true on success, false on failure function Lock($hash, $time = 0) { $results = mysql_query("SELECT GET_LOCK('$hash', $time)"); $string = mysql_fetch_row($results); if (strcmp($string[0], "1") == 0) return true; return false; } // Releases a lock. Ignores errors. function Unlock($hash) { quickQuery("SELECT RELEASE_LOCK('$hash')"); } // Returns true if the lock is available function isFreeLock($lock) { if (Lock($lock, 0)) { Unlock($lock); return true; } return false; } /* Returns true if the user is firewalled, NAT'd, or whatever. * The original tracker had its --nat_check parameter, so * here is my version. * * This code has proven itself to be sufficiently correct, * but will consume system resources when a lot of httpd processes * are lingering around trying to connect to remote hosts. * Consider disabling it under higher loads. */ function isFireWalled($hash, $peerid, $ip, $port) { // NAT checking off? if (!$GLOBALS["NAT"]) return false; $protocol_name = 'BitTorrent protocol'; $theError = ""; // Hoping 10 seconds will be enough $fd = fsockopen($ip, $port, $errno, $theError, 10); if (!$fd) return true; stream_set_timeout($fd, 5, 0); fwrite($fd, chr(strlen($protocol_name)).$protocol_name.hex2bin("0000000000000000"). hex2bin($hash)); $data = fread($fd, strlen($protocol_name)+1+20+20+8); // ideally... fclose($fd); $offset = 0; // First byte: strlen($protocol_name), then the protocol string itself if (ord($data[$offset]) != strlen($protocol_name)) return true; $offset++; if (substr($data, $offset, strlen($protocol_name)) != $protocol_name) return true; $offset += strlen($protocol_name); // 8 bytes reserved, ignore $offset += 8; // Download ID (hash) if (substr($data, $offset, 20) != hex2bin($hash)) return true; $offset+=20; // Peer ID if (substr($data, $offset, 20) != hex2bin($peerid)) return true; return false; } // It's cruel, but if people abuse my tracker, I just might do it. // It pretends to accept the torrent, and reports that you are the // only person connected. function evilReject($ip, $peer_id, $port) { // For those of you who are feeling evil, comment out this line. showError("Torrent is not authorized for use on this tracker."); $peers[0]["peer_id"] = $peer_id; $peers[0]["ip"] = $ip; $peers[0]["port"] = $port; $peers["size"] = 1; $GLOBALS["report_interval"] = 86400; $GLOBALS["min_interval"] = 86000; sendPeerList($peers); exit(0); } function runSpeed($info_hash, $delta) { //stick in our latest data before we calc it out quickQuery("INSERT IGNORE INTO timestamps (info_hash, bytes, delta, sequence) SELECT '$info_hash' AS info_hash, dlbytes, UNIX_TIMESTAMP() - lastSpeedCycle, NULL FROM summary WHERE info_hash=\"$info_hash\""); // mysql blows sometimes so we have to read the data into php before updating it $results = mysql_query('SELECT (MAX(bytes)-MIN(bytes))/SUM(delta), COUNT(*), MIN(sequence) FROM timestamps WHERE info_hash="'.$info_hash.'"' ); $data = mysql_fetch_row($results); summaryAdd("speed", $data[0], true); summaryAdd("lastSpeedCycle", "UNIX_TIMESTAMP()", true); // if we have more than 20 drop the rest if ($data[1] == 21) quickQuery("DELETE FROM timestamps WHERE info_hash=\"$info_hash\" AND sequence=${data[2]}"); else if ($data[1] > 21) // This query requires MySQL 4.0.x, but should rarely be used. quickQuery ('DELETE FROM timestamps WHERE info_hash="'.$info_hash.'" ORDER BY sequence LIMIT '.($data['1'] - 20)); } // Schedules an update to the summary table. It gets so much traffic // that we do all our changes at once. // When called, the column $column for the current info_hash is incremented // by $value, or set to exactly $value if $abs is true. function summaryAdd($column, $value, $abs = false) { if (isset($GLOBALS["summaryupdate"][$column])) { if (!$abs) $GLOBALS["summaryupdate"][$column][0] += $value; else showError(SUMADD_BUG); } else { $GLOBALS["summaryupdate"][$column][0] = $value; $GLOBALS["summaryupdate"][$column][1] = $abs; } } // Even if you're missing PHP 4.3.0, the MHASH extension might be of use. // Someone was kind enought to email this code snippit in. if (function_exists('mhash') && (!function_exists('sha1')) && defined('MHASH_SHA1')) { function sha1($str) { return bin2hex(mhash(MHASH_SHA1,$str)); } } // begin of function added from original function unesc($x) { if (get_magic_quotes_gpc()) return stripslashes($x); return $x; } function mksecret($len = 20) { $ret = ""; for ($i = 0; $i < $len; $i++) $ret .= chr(mt_rand(0, 255)); return $ret; } function logincookie($id, $passhash, $expires = 0x7fffffff) { setcookie("uid", $id, $expires, "/"); setcookie("pass", $passhash, $expires, "/"); } function logoutcookie() { setcookie("uid", "", 0x7fffffff, "/"); setcookie("pass", "", 0x7fffffff, "/"); } function hash_pad($hash) { return str_pad($hash, 20); } /**** validip/getip courtesy of manolete ****/ // IP Validation function validip($ip) { if (!empty($ip) && $ip==long2ip(ip2long($ip))) { // reserved IANA IPv4 addresses // http://www.iana.org/assignments/ipv4-address-space $reserved_ips = array ( array('0.0.0.0','2.255.255.255'), array('10.0.0.0','10.255.255.255'), array('127.0.0.0','127.255.255.255'), array('169.254.0.0','169.254.255.255'), array('172.16.0.0','172.31.255.255'), array('192.0.2.0','192.0.2.255'), array('192.168.0.0','192.168.255.255'), array('255.255.255.0','255.255.255.255') ); foreach ($reserved_ips as $r) { $min = ip2long($r[0]); $max = ip2long($r[1]); if ((ip2long($ip) >= $min) && (ip2long($ip) <= $max)) return false; } return true; } else return false; } // Patched function to detect REAL IP address if it's valid function getip() { if (isset($_SERVER["HTTP_CLIENT_IP"])) { if (validip($_SERVER["HTTP_CLIENT_IP"])) { return $_SERVER["HTTP_CLIENT_IP"]; } } if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) { foreach (explode(",",$_SERVER["HTTP_X_FORWARDED_FOR"]) as $ip) { if (validip(trim($ip))) { return $ip; } } } if (validip(isset($_SERVER["HTTP_X_FORWARDED"])?$_SERVER["HTTP_X_FORWARDED"]:'127.0.0.1')) { return $_SERVER["HTTP_X_FORWARDED"]; } elseif (validip(isset($_SERVER["HTTP_FORWARDED_FOR"])?$_SERVER["HTTP_FORWARDED_FOR"]:'127.0.0.1')) { return $_SERVER["HTTP_FORWARDED_FOR"]; } elseif (validip(isset($_SERVER["HTTP_FORWARDED"])?$_SERVER["HTTP_FORWARDED"]:'127.0.0.1')) { return $_SERVER["HTTP_FORWARDED"]; } elseif (validip(isset($_SERVER["HTTP_X_FORWARDED"])?$_SERVER["HTTP_X_FORWARDED"]:'127.0.0.1')) { return $_SERVER["HTTP_X_FORWARDED"]; } else { return $_SERVER["REMOTE_ADDR"]; } } function userlogin() { global $CURUSER; unset($GLOBALS["CURUSER"]); $ip = getip(); //$_SERVER["REMOTE_ADDR"]; $nip = ip2long($ip); $res = mysql_query("SELECT * FROM bannedip WHERE $nip >= first AND $nip <= last") or sqlerr(__FILE__, __LINE__); if (mysql_num_rows($res) > 0) { header("HTTP/1.0 403 Forbidden"); print("

403 Forbidden

Unauthorized IP address.\n"); die; } // guest if (empty($_COOKIE["uid"]) || empty($_COOKIE["pass"])) $id=1; if (!isset($_COOKIE["uid"])) $_COOKIE["uid"] = 1; $id = max(1 ,$_COOKIE["uid"]); // it's guest if (!$id) $id=1; $res = mysql_query("SELECT users.topicsperpage, users.postsperpage,users.torrentsperpage, users.flag, users.avatar, UNIX_TIMESTAMP(users.lastconnect) AS lastconnect, UNIX_TIMESTAMP(users.joined) AS joined, users.id as uid, users.username, users.password, users.random, users.email, users.language,users.style, users_level.* FROM users INNER JOIN users_level ON users.id_level=users_level.id WHERE users.id = $id") or die(mysql_error()); $row = mysql_fetch_array($res); if (!$row) { $id=1; $res = mysql_query("SELECT users.topicsperpage, users.postsperpage,users.torrentsperpage, users.flag, users.avatar, UNIX_TIMESTAMP(users.lastconnect) AS lastconnect, UNIX_TIMESTAMP(users.joined) AS joined, users.id as uid, users.username, users.password, users.random, users.email, users.language,users.style, users_level.* FROM users INNER JOIN users_level ON users.id_level=users_level.id WHERE users.id = 1"); $row = mysql_fetch_array($res); } if (!isset($_COOKIE["pass"])) $_COOKIE["pass"] = ""; if (($_COOKIE["pass"] != $row["password"]) && $id != 1) { $id=1; $res = mysql_query("SELECT users.topicsperpage, users.postsperpage,users.torrentsperpage, users.flag, users.avatar, UNIX_TIMESTAMP(users.lastconnect) AS lastconnect, UNIX_TIMESTAMP(users.joined) AS joined, users.id as uid, users.username, users.password, users.random, users.email, users.language,users.style, users_level.* FROM users INNER JOIN users_level ON users.id_level=users_level.id WHERE users.id = 1"); $row = mysql_fetch_array($res); } //$ip=$_SERVER["REMOTE_ADDR"]); //$ip=sprintf("%u", ip2long($_SERVER["REMOTE_ADDR"])); if ($id>1) mysql_query("UPDATE users SET lastconnect=NOW(), lip=".$nip.", cip='".AddSlashes($ip)."' WHERE id = $id"); else mysql_query("UPDATE users SET lastconnect=NOW(), lip=0, cip=NULL WHERE id = 1"); $GLOBALS["CURUSER"] = $row; unset($row); } function dbconn($do_clean=false) { global $dbhost, $dbuser, $dbpass, $database, $HTTP_SERVER_VARS; if ($GLOBALS["persist"]) $conres=mysql_pconnect($dbhost, $dbuser, $dbpass); else $conres=mysql_connect($dbhost, $dbuser, $dbpass); if (!$conres) { switch (mysql_errno()) { case 1040: case 2002: if ($HTTP_SERVER_VARS[REQUEST_METHOD] == "GET") die("

".ERR_SERVER_LOAD."

"); else die(ERR_CANT_CONNECT); default: die("[" . mysql_errno() . "] dbconn: mysql_connect: " . mysql_error()); } } mysql_select_db($database) or die(ERR_CANT_OPEN_DB." $database - ".mysql_error()); userlogin(); if ($do_clean) register_shutdown_function("cleandata"); } function cleandata() { global $CURRENTPATH; require_once("$CURRENTPATH/sanity.php"); global $clean_interval; if ((0+$clean_interval)==0) return; $now = time(); $res = mysql_query("SELECT last_time FROM tasks WHERE task='sanity'"); $row = mysql_fetch_array($res); if (!$row) { mysql_query("INSERT INTO tasks (task, last_time) VALUES ('sanity',$now)"); return; } $ts = $row[0]; if ($ts + $clean_interval > $now) return; mysql_query("UPDATE tasks SET last_time=$now WHERE task='sanity' AND last_time = $ts"); if (!mysql_affected_rows()) return; do_sanity(); } function updatedata() { global $CURRENTPATH; require_once("$CURRENTPATH/getscrape.php"); global $update_interval; if ((0+$update_interval)==0) return; $now = time(); $res = @mysql_query("SELECT last_time FROM tasks WHERE task='update'"); $row = @mysql_fetch_array($res); if (!$row) { mysql_query("INSERT INTO tasks (task, last_time) VALUES ('update',$now)"); return; } $ts = $row[0]; if ($ts + $update_interval > $now) return; mysql_query("UPDATE tasks SET last_time=$now WHERE task='update' AND last_time = $ts"); if (!mysql_affected_rows()) return; // $res = mysql_query("SELECT announce_url,info_hash FROM namemap WHERE external='yes' ORDER BY lastupdate ASC LIMIT 5"); $res = @mysql_query("SELECT announce_url FROM namemap WHERE external='yes' ORDER BY lastupdate ASC LIMIT 1"); if (!$res || mysql_num_rows($res)==0) return; // get the url to scrape, take 5 torrent at a time (try to getting multiscrape) $row = mysql_fetch_row($res); $resurl=@mysql_query("SELECT info_hash FROM namemap WHERE external='yes' AND announce_url='".$row[0]."' ORDER BY lastupdate ASC LIMIT 5"); if (!$resurl || mysql_num_rows($resurl)==0) return $combinedinfohash=array(); while ($rhash=mysql_fetch_row($resurl)) $combinedinfohash[]=$rhash[0]; //scrape($row["announce_url"],$row["info_hash"]); scrape($row[0],implode("','",$combinedinfohash)); } function pager($rpp, $count, $href, $opts = array()) { if($rpp!=0) $pages = ceil($count / $rpp); else $pages=0; if (!isset($opts["lastpagedefault"])) $pagedefault = 0; else { $pagedefault = floor(($count - 1) / $rpp); if ($pagedefault < 0) $pagedefault = 0; } $pagename="page"; if (isset($opts["pagename"])) { $pagename=$opts["pagename"]; if (isset($_GET[$opts["pagename"]])) $page = max(0 ,$_GET[$opts["pagename"]]); else $page = $pagedefault; } elseif (isset($_GET["page"])) { $page = 0 + $_GET["page"]; if ($page < 0) $page = $pagedefault; } else $page = $pagedefault; $pager = ""; $mp = $pages - 1; $as = "<< ".PREVIOUS.""; if ($page >= 1) { $pager .= ""; $pager .= $as; $pager .= ""; } else $pager .= $as; $pager .= "      "; $as = "".NEXT." >>"; if ($page < $mp && $mp >= 0) { $pager .= ""; $pager .= $as; $pager .= ""; } else $pager .= $as; if ($count) { $pagerarr = array(); $dotted = 0; $dotspace = 3; $dotend = $pages - $dotspace; $curdotend = $page - $dotspace; $curdotstart = $page + $dotspace; for ($i = 0; $i < $pages; $i++) { if (($i >= $dotspace && $i <= $curdotend) || ($i >= $curdotstart && $i < $dotend)) { if (!$dotted) $pagerarr[] = "..."; $dotted = 1; continue; } $dotted = 0; $start = $i * $rpp + 1; $end = $start + $rpp - 1; if ($end > $count) $end = $count; $text = "$start - $end"; if ($i != $page) $pagerarr[] = "$text"; else $pagerarr[] = "$text"; } $pagerstr = join(" | ", $pagerarr); $pagertop = "

$pager
$pagerstr

\n"; $pagerbottom = "

$pagerstr
$pager

\n"; } else { $pagertop = "

$pager

\n"; $pagerbottom = $pagertop; } $start = $page * $rpp; return array($pagertop, $pagerbottom, "LIMIT $start,$rpp"); } // give back categories recorset function genrelist() { $ret = array(); $res = mysql_query("SELECT * FROM categories ORDER BY sort_index, id"); while ($row = mysql_fetch_array($res)) $ret[] = $row; return $ret; } // this returns all the categories function categories($val="") { echo ""; } // this returns all the subcategories function sub_categories($val="") { echo ""; } // this returns the category of a sub-category function sub_cat($sub) { $c_q = @mysql_fetch_array( @mysql_query("SELECT name FROM categories WHERE id='$sub'") ); $name = unesc($c_q["name"]); return $name; } function style_list() { $ret = array(); $res = mysql_query("SELECT * FROM style ORDER BY id"); while ($row = mysql_fetch_array($res)) $ret[] = $row; return $ret; } function language_list() { $ret = array(); $res = mysql_query("SELECT * FROM language ORDER BY language"); while ($row = mysql_fetch_array($res)) $ret[] = $row; return $ret; } function flag_list() { $ret = array(); $res = mysql_query("SELECT * FROM countries ORDER BY name"); while ($row = mysql_fetch_array($res)) $ret[] = $row; return $ret; } function stdfoot($normalpage=true, $update=true) { global $STYLEPATH; if ($normalpage) include($STYLEPATH."/footer.php"); print("\n\n"); if ($update) register_shutdown_function("updatedata"); } function linkcolor($num) { if (!$num) return "red"; if ($num == 1) return "yellow"; return "green"; } function format_quote($text) { $string=$text; $prev_string = ""; while ($prev_string != $string) { $prev_string = $string; $string = preg_replace("/\[quote\]\s*((\s|.)+?)\s*\[\/quote\]\s*/i", "
".QUOTE.":
\\1

", $string); $string = preg_replace("/\[quote=(.+?)\]\s*((\s|.)+?)\s*\[\/quote\]\s*/i", "
\${1} ".WROTE.":
\\2

", $string); // code $string = preg_replace("/\[code\]\s*((\s|.)+?)\s*\[\/code\]\s*/i", "
Code
\\1

", $string); } return $string; } function format_comment($text, $strip_html = true) { global $smilies, $privatesmilies, $BASEURL; $s = $text; if ($strip_html) $s = htmlspecialchars($s); $s = unesc($s); $f=@fopen("badwords.txt","r"); if ($f && filesize ("badwords.txt")!=0) { $bw=fread($f,filesize("badwords.txt")); $badwords=explode("\n",$bw); for ($i=0;$i", $s); // [b]Bold[/b] $s = preg_replace("/\[b\]((\s|.)+?)\[\/b\]/", "\\1", $s); $s = preg_replace("/\[B\]((\s|.)+?)\[\/B\]/", "\\1", $s); // [i]Italic[/i] $s = preg_replace("/\[i\]((\s|.)+?)\[\/i\]/", "\\1", $s); $s = preg_replace("/\[I\]((\s|.)+?)\[\/I\]/", "\\1", $s); // [u]Underline[/u] $s = preg_replace("/\[u\]((\s|.)+?)\[\/u\]/", "\\1", $s); $s = preg_replace("/\[U\]((\s|.)+?)\[\/U\]/", "\\1", $s); // [img]http://www/image.gif[/img] $s = preg_replace("/\[img\](http:\/\/[^\s'\"<>]+(\.gif|\.jpg|\.png))\[\/img\]/", "", $s); $s = preg_replace("/\[IMG\](http:\/\/[^\s'\"<>]+(\.gif|\.jpg|\.png))\[\/IMG\]/", "", $s); // [img=http://www/image.gif] $s = preg_replace("/\[img=(http:\/\/[^\s'\"<>]+(\.gif|\.jpg|\.png))\]/", "", $s); $s = preg_replace("/\[IMG=(http:\/\/[^\s'\"<>]+(\.gif|\.jpg|\.png))\]/", "", $s); // [color=blue]Text[/color] $s = preg_replace( "/\[color=([a-zA-Z]+)\]((\s|.)+?)\[\/color\]/i", "\\2", $s); // [color=#ffcc99]Text[/color] $s = preg_replace( "/\[color=(#[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9])\]((\s|.)+?)\[\/color\]/i", "\\2", $s); // [url=http://www.example.com]Text[/url] $s = preg_replace( "/\[url=((http|ftp|https|ftps|irc):\/\/[^<>\s]+?)\]((\s|.)+?)\[\/url\]/i", "\\3", $s); // [url]http://www.example.com[/url] $s = preg_replace( "/\[url\]((http|ftp|https|ftps|irc):\/\/[^<>\s]+?)\[\/url\]/i", "\\1", $s); // [size=4]Text[/size] $s = preg_replace( "/\[size=([1-7])\]((\s|.)+?)\[\/size\]/i", "\\2", $s); // [font=Arial]Text[/font] $s = preg_replace( "/\[font=([a-zA-Z ,]+)\]((\s|.)+?)\[\/font\]/i", "\\2", $s); $s=format_quote($s); // Linebreaks $s = nl2br($s); // Maintain spacing $s = str_replace(" ", "  ", $s); reset($smilies); while (list($code, $url) = each($smilies)) $s = str_replace($code, "", $s); reset($privatesmilies); while (list($code, $url) = each($privatesmilies)) $s = str_replace($code, "", $s); return $s; } function image_or_link($image,$style="",$link="") { if ($image=="") return $link; elseif (file_exists($image)) return "\"$link\"/"; else return $link; } function standardheader($title,$normalpage=true,$idlang=0) { global $CURUSER, $SITENAME, $STYLEPATH, $USERLANG,$time_start, $gzip, $GZIP_ENABLED; $time_start = get_microtime(); // default settings for blocks/menu if (!isset($GLOBALS["charset"])) $GLOBALS["charset"] = "iso-8859-1"; // controll if client can handle gzip if ($GZIP_ENABLED) { if (stristr($_SERVER["HTTP_ACCEPT_ENCODING"],"gzip") && extension_loaded('zlib') && ini_get("zlib.output_compression") == 0) { if (ini_get('output_handler')!='ob_gzhandler') { ob_start("ob_gzhandler"); $gzip='enabled'; } else { ob_start(); $gzip='enabled'; } } else { ob_start(); $gzip='disabled'; } } else $gzip='disabled'; header("Content-Type: text/html; charset=".$GLOBALS["charset"]); if ($title == "") $title = unesc($SITENAME); else $title = unesc($SITENAME) . " - " . htmlspecialchars($title); ?> <?echo $title; ?> "); ?> \n\n"); die; } require_once($USERLANG); if (!file_exists($style)) { err_msg("Error!","Missing Style!"); print_version(); print("\n\n"); die; } if ($normalpage) require_once($STYLEPATH."/header.php"); } function err_msg($heading="Error!",$string) { // just in case not found the language if (!defined("BACK")) define("BACK","Back"); print("

\n"); print("\n"); print("
\n"); print("$heading
$string

\n"); print("
".BACK."
"); } function sqlesc($x) { return "'".mysql_escape_string($x)."'"; } function print_news($limit=0) { global $CURUSER, $limitqry, $adm_menu; $output=""; $model="" ."\n{admin_menu}" ."\n
".POSTED_BY.": {user_name}" ."\n
".POSTED_DATE.": {news_date}" ."\n
" ."\n".TITLE.": {news_title}

" ."\n" ."\n" ."\n
{news}

"; if ($limit>0) $limitqry="LIMIT $limit"; $res=mysql_query("select news.id, news.title,news.news,UNIX_TIMESTAMP(news.date) as news_date,users.username FROM news INNER JOIN users on users.id=news.user_id ORDER BY date DESC $limitqry "); while ($rows=mysql_fetch_array($res)) { if ($CURUSER["edit_news"]=="yes" || $CURUSER["delete_news"]=="yes") $adm_menu=""; if ($CURUSER["edit_news"]=="yes") $adm_menu.="".ADD."   ".EDIT.""; if ($CURUSER["delete_news"]=="yes") $adm_menu.="   ".DELETE.""; else $adm_menu.=""; $news=format_comment($rows["news"]); $output = eregi_replace("\{user_name}", unesc($rows["username"]), $model); $output = eregi_replace("\{admin_menu}", $adm_menu, $output); $output = eregi_replace("\{news_date}", date("d/m/Y H:i",$rows["news_date"]), $output); $output = eregi_replace("\{news_title}", unesc($rows["title"]), $output); $output = eregi_replace("\{news}", $news, $output); print $output; } if ($output=="") { print("
".NO_NEWS."...
"); if ($CURUSER["edit_news"]=="yes") print("
\"".ADD."\"
"); } } function block_begin($title="-",$colspan=1,$calign="justify") { print("
\n" ."\t\n" ."\t\t" ."\t\n" ."\t\n" ."\t\t\n" ."\t\n" ."\t\n" ."\t\t\n" ."\t\n" ."\t\n" ."\t\t" ."\t\n" ."
spacer
$title
\n" ."\t\n" ."\t
"); } function block_end($colspan=1) { print("\t\t
\n" ."\t\t
spacer
"); } function print_users() { global $CURUSER, $STYLEPATH; if (!isset($_GET["searchtext"])) $_GET["searchtext"] = ""; if (!isset($_GET["level"])) $_GET["level"] = ""; $search=$_GET["searchtext"]; $addparams=""; if ($search!="") { $where=" AND users.username LIKE '%".mysql_escape_string($_GET["searchtext"])."%'"; $addparams="searchtext=$search"; } else $where=""; $level=intval(0+$_GET["level"]); if ($level>0) { $where.=" AND users.id_level=$level"; if ($addparams!="") $addparams.="&level=$level"; else $addparams="level=$level"; } // getting order if (isset($_GET["order"])) $order=htmlspecialchars($_GET["order"]); else $order="joined"; if (isset($_GET["by"])) $by=htmlspecialchars($_GET["by"]); else $by="ASC"; if ($addparams!="") $addparams.="&"; $scriptname=$_SERVER["PHP_SELF"]; $res=mysql_query("select COUNT(*) FROM users INNER JOIN users_level ON users.id_level=users_level.id WHERE users.id>1 $where") or die(mysql_error()); $row = mysql_fetch_row($res); $count = $row[0]; list($pagertop, $pagerbottom, $limit) = pager(20, $count, "users.php?".$addparams."order=$order&by=$by&"); if ($by=="ASC") $mark=" ↑"; else $mark=" ↓"; ?>
"); ?>
 
".EDIT.""); if ($CURUSER["delete_users"]=="yes") print(""); else print (""); $query="select prefixcolor, suffixcolor, users.id, downloaded,uploaded, IF(downloaded>0,uploaded/downloaded,0) as ratio, username,level,UNIX_TIMESTAMP(joined) AS joined,UNIX_TIMESTAMP(lastconnect) AS lastconnect, flag, flagpic, name FROM users INNER JOIN users_level ON users.id_level=users_level.id LEFT JOIN countries ON users.flag=countries.id WHERE users.id>1 $where ORDER BY $order $by $limit"; //print($query); $rusers=mysql_query($query); if (mysql_num_rows($rusers)==0) // flag hack print(""); else { while ($row_user=mysql_fetch_array($rusers)) { print("\n"); print(""); print(""); print(""); print(""); print(""); //user ratio if (max(0,$row_user["downloaded"])>0) $ratio=number_format($row_user["uploaded"]/$row_user["downloaded"],2); else $ratio="oo"; print(""); print(""); if ($CURUSER["edit_users"]=="yes") print(""); if ($CURUSER["delete_users"]=="yes") print(""); print("\n"); } } print("
".USER_NAME."".($order=="username"?$mark:"");?> ".USER_LEVEL."".($order=="level"?$mark:"")?> ".USER_JOINED."".($order=="joined"?$mark:"");?> ".USER_LASTACCESS."".($order=="lastconnect"?$mark:"");?> ".PEER_COUNTRY."".($order=="flag"?$mark:"");?> ".RATIO."".($order=="ratio"?$mark:"");?> ".DELETE."
".NO_USERS_FOUND."
".unesc($row_user["prefixcolor"]).unesc($row_user["username"]).unesc($row_user["suffixcolor"])."".$row_user["level"]."".($row_user["joined"]==0 ? NOT_AVAILABLE : date("d/m/Y H:i:s",$row_user["joined"]))."".($row_user["lastconnect"]==0 ? NOT_AVAILABLE : date("d/m/Y H:i:s",$row_user["lastconnect"]))."". ( $row_user["flag"] == 0 ? "".UNKNOWN."" : "" . $row_user[")."$ratio".image_or_link("$STYLEPATH/pm.png","","PM")."".image_or_link("$STYLEPATH/edit.png","",EDIT)."".image_or_link("$STYLEPATH/delete.png","",DELETE)."
\n
\n
"); } function makesize($bytes) { if (abs($bytes) < 1000 * 1024) return number_format($bytes / 1024, 2) . " KB"; if (abs($bytes) < 1000 * 1048576) return number_format($bytes / 1048576, 2) . " MB"; if (abs($bytes) < 1000 * 1073741824) return number_format($bytes / 1073741824, 2) . " GB"; return number_format($bytes / 1099511627776, 2) . " TB"; } function redirect($redirecturl) { // using javascript for redirecting // some hosting has warning enabled and this is causing // problem withs header() redirecting... print("If your browser doesn't have javascript enabled, click here "); print(""); } function textbbcode($form,$name,$content="") { ?>
)" /> )" /> )" /> )" /> )" /> )" /> )" /> )" />
"); print("\n"); $count++; if ($count % 4==0) print(""); } ?>
0) && (floor($id) == $id); } function begin_table($fullwidth = false, $padding = 5) { if ($fullwidth) $width = " width=100%"; else $width = ""; print("\n"); } function end_table() { print("
\n"); } function begin_frame($caption = "", $center = false, $padding = 10) { if ($caption) print("

$caption

\n"); if ($center) $tdextra = " align=center"; else $tdextra =""; print("\n"); } function end_frame() { print("
\n"); } function get_date_time($timestamp = 0) { if ($timestamp) return date("d/m/Y H:i:s", $timestamp); else return gmdate("d/m/Y H:i:s"); } function stderr($heading, $text) { err_msg($heading,$text); stdfoot(); die; } function encodehtml($s, $linebreaks = true) { $s = str_replace("<", "<", str_replace("&", "&", $s)); if ($linebreaks) $s = nl2br($s); return $s; } function get_elapsed_time($ts) { $mins = floor((time() - $ts) / 60); $hours = floor($mins / 60); $mins -= $hours * 60; $days = floor($hours / 24); $hours -= $days * 24; $weeks = floor($days / 7); $days -= $weeks * 7; $t = ""; if ($weeks > 0) return "$weeks week" . ($weeks > 1 ? "s" : ""); if ($days > 0) return "$days day" . ($days > 1 ? "s" : ""); if ($hours > 0) return "$hours hour" . ($hours > 1 ? "s" : ""); if ($mins > 0) return "$mins min" . ($mins > 1 ? "s" : ""); return "< 1 min"; } function sql_timestamp_to_unix_timestamp($s) { return mktime(substr($s, 11, 2), substr($s, 14, 2), substr($s, 17, 2), substr($s, 5, 2), substr($s, 8, 2), substr($s, 0, 4)); } function gmtime() { return strtotime(get_date_time()); } function sqlerr($file = '', $line = '') { print("" . "

".ERR_SQL_ERR."

\n" . "" . mysql_error() . ($file != '' && $line != '' ? "

in $file, line $line

" : "") . "
"); die; } function attach_frame($padding = 10) { print("\n"); } function httperr($code = 404) { header("HTTP/1.0 404 Not found"); print("

".ERR_NOT_FOUND."

\n"); exit(); } function peercolor($num) { if(!$num){ return "#FF0000"; } elseif($num == 1){ return "#BEC635"; } else { return "green"; } } // ---------------------------------------------------------------- class ocr_captcha { var $key; // ultra private static text var $long; // size of text var $lx; // width of picture var $ly; // height of picture var $nb_noise; // nb of background noisy characters var $filename; // file of captcha picture stored on disk var $imagetype="png"; // can also be "png"; var $public_key; // public key var $font_file="./include/adlibn.ttf"; function ocr_captcha($long=6,$lx=120,$ly=30,$nb_noise=25) { $this->key=md5("A nicely little text to stay private and use for generate private key"); $this->long=$long; $this->lx=$lx; $this->ly=$ly; $this->nb_noise=$nb_noise; $this->public_key=substr(md5(uniqid(rand(),true)),0,$this->long); // generate public key with entropy } function get_filename($public="") { global $TORRENTSDIR; if ($public=="") $public=$this->public_key; return $TORRENTSDIR."/".$public.".".$this->imagetype; } // generate the private text coming from the public text, using $this->key (not to be public!!), all you have to do is here to change the algorithm function generate_private($public="") { if ($public=="") $public=$this->public_key; return substr(md5($this->key.$public),16-$this->long/2,$this->long); } // check if the public text is link to the private text function check_captcha($public,$private) { // when check, destroy picture on disk if (file_exists($this->get_filename($public))) unlink($this->get_filename($public)); return (strtolower($private)==strtolower($this->generate_private($public))); } // display a captcha picture with private text and return the public text function make_captcha($noise=true) { $private_key = $this->generate_private(); $image = imagecreatetruecolor($this->lx,$this->ly); $back=ImageColorAllocate($image,intval(rand(224,255)),intval(rand(224,255)),intval(rand(224,255))); ImageFilledRectangle($image,0,0,$this->lx,$this->ly,$back); if ($noise) { // rand characters in background with random position, angle, color for ($i=0;$i<$this->nb_noise;$i++) { $size=intval(rand(6,14)); $angle=intval(rand(0,360)); $x=intval(rand(10,$this->lx-10)); $y=intval(rand(0,$this->ly-5)); $color=imagecolorallocate($image,intval(rand(160,224)),intval(rand(160,224)),intval(rand(160,224))); $text=chr(intval(rand(45,250))); ImageTTFText ($image,$size,$angle,$x,$y,$color,$this->font_file,$text); } } else { // random grid color for ($i=0;$i<$this->lx;$i+=10) { $color=imagecolorallocate($image,intval(rand(160,224)),intval(rand(160,224)),intval(rand(160,224))); imageline($image,$i,0,$i,$this->ly,$color); } for ($i=0;$i<$this->ly;$i+=10) { $color=imagecolorallocate($image,intval(rand(160,224)),intval(rand(160,224)),intval(rand(160,224))); imageline($image,0,$i,$this->lx,$i,$color); } } // private text to read for ($i=0,$x=5; $i<$this->long;$i++) { $r=intval(rand(0,128)); $g=intval(rand(0,128)); $b=intval(rand(0,128)); $color = ImageColorAllocate($image, $r,$g,$b); $shadow= ImageColorAllocate($image, $r+128, $g+128, $b+128); $size=intval(rand(12,17)); $angle=intval(rand(-30,30)); $text=strtoupper(substr($private_key,$i,1)); ImageTTFText($image,$size,$angle,$x+2,26,$shadow,$this->font_file,$text); ImageTTFText($image,$size,$angle,$x,24,$color,$this->font_file,$text); $x+=$size+2; } if ($this->imagetype=="jpg") imagejpeg($image, $this->get_filename(), 100); else imagepng($image, $this->get_filename()); ImageDestroy($image); } function display_captcha($noise=true) { $this->make_captcha($noise); $res="\n"; $res.="\n"; return $res; } } // ---------------------------------------------------------------- // v.1.3 function write_log($text,$reason="add") { GLOBAL $CURUSER, $LOG_ACTIVE; if ($LOG_ACTIVE) { $text = sqlesc($text); $reason=sqlesc($reason); mysql_query("INSERT INTO logs (added, txt,type,user) VALUES(UNIX_TIMESTAMP(), $text, $reason,'".$CURUSER["username"]."')") or sqlerr(__FILE__, __LINE__); } } // EOF ?>0) { // make new columns only if at least 1 block ?> 0) { ?>