<?php
if (!function_exists("bcsub"))
{
function bcsub($first_num, $second_num)
{
$fn=max(0,$first_num);
$sn=max(0,$second_num);
return $fn-$sn;
}
}
// Reports an error to the client in $message.
// Any other output will confuse the client, so please don't do that.
function show_error($message, $log=false)
{
if ($log)
error_log("BtiTracker: ERROR ($message)");
echo "d14:failure reason".strlen($message).":$message"."e";
exit(0);
}
function verifyHash($input)
{
if (strlen($input) === 40 && preg_match('/^[0-9a-f]+$/', $input))
return true;
else
return false;
}
/**** validip/getip courtesy of manolete <manolete@myway.com> ****/
// 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 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 );
}
// 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;
}
#========================================
#getAgent function by deliopoulos
#========================================
function StdDecodePeerId($id_data, $id_name){
$version_str = "";
for ($i=0; $i<=strlen($id_data); $i++){
$c = $id_data[$i];
if ($id_name=="BitTornado" || $id_name=="ABC") {
if ($c!='-' && ctype_digit($c)) $version_str .= "$c.";
elseif ($c!='-' && ctype_alpha($c)) $version_str .= (ord($c)-55).".";
else break;
}
elseif($id_name=="BitComet"||$id_name=="BitBuddy"||$id_name=="Lphant"||$id_name=="BitPump"||$id_name=="BitTorrent Plus! v2") {
if ($c != '-' && ctype_alnum($c)){
$version_str .= "$c";
if($i==0) $version_str = intval($version_str) .".";
}
else{
$version_str .= ".";
break;
}
}
else {
if ($c != '-' && ctype_alnum($c)) $version_str .= "$c.";
else break;
}
}
$version_str = substr($version_str,0,strlen($version_str)-1);
return "$id_name $version_str";
}
function MainlineDecodePeerId($id_data, $id_name){
$version_str = "";
for ($i=0; $i<=strlen($id_data); $i++){
$c = $id_data[$i];
if ($c != '-' && ctype_alnum($c)) $version_str .= "$c.";
}
$version_str = substr($version_str,0,strlen($version_str)-1);
return "$id_name $version_str";
}
function DecodeVersionString ($ver_data, $id_name){
$version_str = "";
$version_str .= intval(ord($ver_data[0]) + 0).".";
$version_str .= intval(ord($ver_data[1])/10 + 0);
$version_str .= intval(ord($ver_data[1])%10 + 0);
return "$id_name $version_str";
}
function getagent($httpagent, $peer_id="") {
if($peer_id!="") $peer_id=hex2bin($peer_id);
if(substr($peer_id,0,3)=='-AX') return StdDecodePeerId(substr($peer_id,4,4),"BitPump"); # AnalogX BitPump
if(substr($peer_id,0,3)=='-BB') return StdDecodePeerId(substr($peer_id,3,5),"BitBuddy"); # BitBuddy
if(substr($peer_id,0,3)=='-BC') return StdDecodePeerId(substr($peer_id,4,4),"BitComet"); # BitComet
if(substr($peer_id,0,3)=='-BS') return StdDecodePeerId(substr($peer_id,3,7),"BTSlave"); # BTSlave
if(substr($peer_id,0,3)=='-BX') return StdDecodePeerId(substr($peer_id,3,7),"BittorrentX"); # BittorrentX
if(substr($peer_id,0,3)=='-CT') return "Ctorrent $peer_id[3].$peer_id[4].$peer_id[6]"; # CTorrent
if(substr($peer_id,0,3)=='-KT') return StdDecodePeerId(substr($peer_id,3,7),"KTorrent"); # KTorrent
if(substr($peer_id,0,3)=='-LT') return StdDecodePeerId(substr($peer_id,3,7),"libtorrent"); # libtorrent
if(substr($peer_id,0,3)=='-LP') return StdDecodePeerId(substr($peer_id,4,4),"Lphant"); # Lphant
if(substr($peer_id,0,3)=='-MP') return StdDecodePeerId(substr($peer_id,3,7),"MooPolice"); # MooPolice
if(substr($peer_id,0,3)=='-MT') return StdDecodePeerId(substr($peer_id,3,7),"Moonlight"); # MoonlightTorrent
if(substr($peer_id,0,3)=='-PO') return StdDecodePeerId(substr($peer_id,3,7),"PO Client"); #unidentified clients with versions
if(substr($peer_id,0,3)=='-QT') return StdDecodePeerId(substr($peer_id,3,7),"Qt 4 Torrent"); # Qt 4 Torrent
if(substr($peer_id,0,3)=='-RT') return StdDecodePeerId(substr($peer_id,3,7),"Retriever"); # Retriever
if(substr($peer_id,0,3)=='-S2') return StdDecodePeerId(substr($peer_id,3,7),"S2 Client"); #unidentified clients with versions
if(substr($peer_id,0,3)=='-SB') return StdDecodePeerId(substr($peer_id,3,7),"Swiftbit"); # Swiftbit
if(substr($peer_id,0,3)=='-SN') return StdDecodePeerId(substr($peer_id,3,7),"ShareNet"); # ShareNet
if(substr($peer_id,0,3)=='-SS') return StdDecodePeerId(substr($peer_id,3,7),"SwarmScope"); # SwarmScope
if(substr($peer_id,0,3)=='-SZ') return StdDecodePeerId(substr($peer_id,3,7),"Shareaza"); # Shareaza
if(preg_match("/^RAZA ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/", $httpagent, $matches)) return "Shareaza $matches[1]";
if(substr($peer_id,0,3)=='-TN') return StdDecodePeerId(substr($peer_id,3,7),"Torrent.NET"); # Torrent.NET
if(substr($peer_id,0,3)=='-TR') return StdDecodePeerId(substr($peer_id,3,7),"Transmission"); # Transmission
if(substr($peer_id,0,3)=='-TS') return StdDecodePeerId(substr($peer_id,3,7),"TorrentStorm"); # Torrentstorm
if(substr($peer_id,0,3)=='-UR') return StdDecodePeerId(substr($peer_id,3,7),"UR Client"); # unidentified clients with versions
if(substr($peer_id,0,3)=='-UT') return StdDecodePeerId(substr($peer_id,3,7),"uTorrent"); # uTorrent
if(substr($peer_id,0,3)=='-XT') return StdDecodePeerId(substr($peer_id,3,7),"XanTorrent"); # XanTorrent
if(substr($peer_id,0,3)=='-ZT') return StdDecodePeerId(substr($peer_id,3,7),"ZipTorrent"); # ZipTorrent
if(substr($peer_id,0,3)=='-bk') return StdDecodePeerId(substr($peer_id,3,7),"BitKitten"); # BitKitten
if(substr($peer_id,0,3)=='-lt') return StdDecodePeerId(substr($peer_id,3,7),"libTorrent"); # libTorrent
if(substr($peer_id,0,3)=='-pX') return StdDecodePeerId(substr($peer_id,3,7),"pHoeniX"); # pHoeniX
if(substr($peer_id,0,2)=='BG') return StdDecodePeerId(substr($peer_id,2,4),"BTGetit"); # BTGetit
if(substr($peer_id,2,2)=='BM') return DecodeVersionString(substr($peer_id,0,2),"BitMagnet"); # BitMagnet
if(substr($peer_id,0,2)=='OP') return StdDecodePeerId(substr($peer_id,2,4),"Opera"); # Opera
if(substr($peer_id,0,4)=='270-') return "GreedBT 2.7.0"; # GreedBT
if(substr($peer_id,0,4)=='271-') return "GreedBT 2.7.1"; # GreedBT 2.7.1
if(substr($peer_id,0,4)=='346-') return "TorrentTopia"; # TorrentTopia
if(substr($peer_id,0,3)=='-AR') return "Arctic Torrent"; # Arctic (no way to know the version)
if(substr($peer_id,0,3)=='-G3') return "G3 Torrent"; # G3 Torrent
if(substr($peer_id,0,6)=='BTDWV-') return "Deadman Walking"; # Deadman Walking
if(substr($peer_id,5,7)=='Azureus') return "Azureus 2.0.3.2"; # Azureus 2.0.3.2
if(substr($peer_id,0,8)=='PRC.P---') return "BitTorrent Plus! II"; # BitTorrent Plus! II
if(substr($peer_id,0,8)=='P87.P---') return "BitTorrent Plus!"; # BitTorrent Plus!
if(substr($peer_id,0,4)=='Plus') return StdDecodePeerId(substr($peer_id,4,5),"BitTorrent Plus! v2"); # BitTorrent Plus! v2 (not 100% sure on this one)
if(substr($peer_id,0,8)=='S587Plus') return "BitTorrent Plus!"; # BitTorrent Plus!
if(substr($peer_id,0,7)=='martini') return "Martini Man"; # Martini Man
if(substr($peer_id,4,6)=='btfans') return "SimpleBT"; # SimpleBT
if(substr($peer_id,3,9)=='SimpleBT?') return "SimpleBT"; # SimpleBT
if(ereg("MFC_Tear_Sample", $httpagent)) return "SimpleBT";
if(substr($peer_id,0,5)=='btuga') return "BTugaXP"; # BTugaXP
if(substr($peer_id,0,5)=='BTuga') return "BTuga"; # BTugaXP
if(substr($peer_id,0,5)=='oernu') return "BTugaXP"; # BTugaXP
if(substr($peer_id,0,10)=='DansClient') return "XanTorrent"; # XanTorrent
if(substr($peer_id,0,16)=='Deadman Walking-') return "Deadman"; # Deadman client
if(substr($peer_id,0,8)=='XTORR302') return "TorrenTres 0.0.2"; # TorrenTres
if(substr($peer_id,0,7)=='turbobt') return "TurboBT ".(substr($peer_id,7,5)); # TurboBT
if(substr($peer_id,0,7)=='a00---0') return "Swarmy"; # Swarmy
if(substr($peer_id,0,7)=='a02---0') return "Swarmy"; # Swarmy
if(substr($peer_id,0,7)=='T00---0') return "Teeweety"; # Teeweety
if(substr($peer_id,0,7)=='rubytor') return "Ruby Torrent v".ord($peer_id[7]); # Ruby Torrent
if(substr($peer_id,0,5)=='Mbrst') return MainlineDecodePeerId(substr($peer_id,5,5),"burst!"); # burst!
if(substr($peer_id,0,4)=='btpd') return "BT Protocol Daemon ".(substr($peer_id,5,3)); # BT Protocol Daemon
if(substr($peer_id,0,8)=='XBT022--') return "BitTorrent Lite"; # BitTorrent Lite based on XBT code
if(substr($peer_id,0,3)=='XBT') return StdDecodePeerId(substr($peer_id,3,3), "XBT"); # XBT Client
if(substr($peer_id,0,4)=='-BOW') return StdDecodePeerId(substr($peer_id,4,5),"Bits on Wheels"); # Bits on Wheels
if(substr($peer_id,1,2)=='ML') return MainlineDecodePeerId(substr($peer_id,3,5),"MLDonkey"); # MLDonkey
if($peer_id[0]=='A') return StdDecodePeerId(substr($peer_id,1,9),"ABC"); # ABC
if($peer_id[0]=='R') return StdDecodePeerId(substr($peer_id,1,5),"Tribler"); # Tribler
if($peer_id[0]=='M'){
if(preg_match("/^Python/", $httpagent, $matches)) return "Spoofing BT Client"; # Spoofing BT Client
return MainlineDecodePeerId(substr($peer_id,1,7),"Mainline"); # Mainline BitTorrent with version
}
if($peer_id[0]=='O') return StdDecodePeerId(substr($peer_id,1,9),"Osprey Permaseed"); # Osprey Permaseed
if($peer_id[0]=='S'){
if(preg_match("/^BitTorrent\/3.4.2/", $httpagent, $matches)) return "Spoofing BT Client"; # Spoofing BT Client
return StdDecodePeerId(substr($peer_id,1,9),"Shad0w"); # Shadow's client
}
if($peer_id[0]=='T'){
if(preg_match("/^Python/", $httpagent, $matches)) return "Spoofing BT Client"; # Spoofing BT Client
return StdDecodePeerId(substr($peer_id,1,9),"BitTornado"); # BitTornado
}
if($peer_id[0]=='U') return StdDecodePeerId(substr($peer_id,1,9),"UPnP"); # UPnP NAT Bit Torrent
# Azureus / Localhost
if(substr($peer_id,0,3)=='-AZ') {
if(preg_match("/^Localhost ([0-9]+\.[0-9]+\.[0-9]+)/", $httpagent, $matches)) return "Localhost $matches[1]";
if(preg_match("/^BitTorrent\/3.4.2/", $httpagent, $matches)) return "Spoofing BT Client"; # Spoofing BT Client
if(preg_match("/^Python/", $httpagent, $matches)) return "Spoofing BT Client"; # Spoofing BT Client
return StdDecodePeerId(substr($peer_id,3,7),"Azureus");
}
if(ereg("Azureus", $peer_id)) return "Azureus 2.0.3.2";
# BitComet/BitLord/BitVampire/Modded FUTB BitComet
if(substr($peer_id,0,4)=='exbc' || substr($peer_id,1,3)=='UTB'){
if(substr($peer_id,0,4)=='FUTB') return DecodeVersionString(substr($peer_id,4,2),"BitComet Mod1");
elseif(substr($peer_id,0,4)=='xUTB') return DecodeVersionString(substr($peer_id,4,2),"BitComet Mod2");
elseif(substr($peer_id,6,4)=='LORD') return DecodeVersionString(substr($peer_id,4,2),"BitLord");
elseif(substr($peer_id,6,3)=='---' && DecodeVersionString(substr($peer_id,4,2),"BitComet")=='BitComet 0.54') return "BitVampire";
else return DecodeVersionString(substr($peer_id,4,2),"BitComet");
}
# Rufus
if(substr($peer_id,2,2)=='RS'){
for ($i=0; $i<=strlen(substr($peer_id,4,9)); $i++){
$c = $peer_id[$i+4];
if (ctype_alnum($c) || $c == chr(0)) $rufus_chk = true;
else break;
}
if ($rufus_chk) return DecodeVersionString(substr($peer_id,0,2),"Rufus"); # Rufus
}
# BitSpirit
if(substr($peer_id,14,6)=='HTTPBT' || substr($peer_id,16,4)=='UDP0') {
if(substr($peer_id,2,2)=='BS') {
if($peer_id[1]==chr(0)) return "BitSpirit v1";
if($peer_id[1]== chr(2)) return "BitSpirit v2";
}
return "BitSpirit";
}
#BitSpirit
if(substr($peer_id,2,2)=='BS') {
if($peer_id[1]==chr(0)) return "BitSpirit v1";
if($peer_id[1]==chr(2)) return "BitSpirit v2";
return "BitSpirit";
}
# eXeem beta
if(substr($peer_id,0,3)=='-eX') {
$version_str = "";
$version_str .= intval($peer_id[3],16).".";
$version_str .= intval($peer_id[4],16);
return "eXeem $version_str";
}
if(substr($peer_id,0,2)=='eX') return "eXeem"; # eXeem beta .21
if(substr($peer_id,0,12)==(chr(0)*12) && $peer_id[12]==chr(97) && $peer_id[13]==chr(97)) return "Experimental 3.2.1b2"; # Experimental 3.2.1b2
if(substr($peer_id,0,12)==(chr(0)*12) && $peer_id[12]==chr(0) && $peer_id[13]==chr(0)) return "Experimental 3.1"; # Experimental 3.1
//if(substr($peer_id,0,12)==(chr(0)*12)) return "Mainline (obsolete)"; # Mainline BitTorrent (obsolete)
//return "$httpagent [$peer_id]";
return "Unknown client";
}
#========================================
#getAgent function by deliopoulos
#========================================
?><?php
// 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
show_error("Tracker bug calling summaryAdd");
}
else
{
$GLOBALS["summaryupdate"][$column][0] = $value;
$GLOBALS["summaryupdate"][$column][1] = $abs;
}
}
ignore_user_abort(1);
$GLOBALS["peer_id"] = "";
$summaryupdate = array();
$BASEPATH=dirname(__FILE__);
require("$BASEPATH/include/config.php");
require("$BASEPATH/include/common.php");
error_reporting(0);
// connect to db
if ($GLOBALS["persist"])
$conres=mysql_pconnect($dbhost, $dbuser, $dbpass) or show_error("Tracker errore - mysql_connect: " . mysql_error());
else
$conres=mysql_connect($dbhost, $dbuser, $dbpass) or show_error("Tracker errore - mysql_connect: " . mysql_error());
mysql_select_db($database) or show_error("Tracker errore - $database - ".mysql_error());
// connection is done ok
if (isset ($_GET["pid"]))
$pid = $_GET["pid"];
else
$pid = "";
if (strpos($pid, "?"))
{
$tmp = substr($pid , strpos($pid , "?"));
$pid = substr($pid , 0,strpos($pid , "?"));
$tmpname = substr($tmp, 1, strpos($tmp, "=")-1);
$tmpvalue = substr($tmp, strpos($tmp, "=")+1);
$_GET[$tmpname] = $tmpvalue;
}
// Many thanks to KktoMx for figuring out this head-ache causer,
// and to bideomex for showing me how to do it PROPERLY... :)
if (get_magic_quotes_gpc())
{
$info_hash = bin2hex(stripslashes($_GET["info_hash"]));
$peer_id = bin2hex(stripslashes($_GET["peer_id"]));
}
else
{
$info_hash = bin2hex($_GET["info_hash"]);
$peer_id = bin2hex($_GET["peer_id"]);
}
$iscompact=(isset($_GET["compact"])?$_GET["compact"]=='1':false);
// 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' && !$iscompact)
{
// only for non compact
ob_start("ob_gzhandler");
}
else
{
ob_start();
}
}
else
{
ob_start();
}
}
// end gzip controll
header("Content-type: text/plain");
header("Pragma: no-cache");
// Error: no web browsers allowed
$agent = mysql_escape_string($_SERVER["HTTP_USER_AGENT"]);
// Deny access made with a browser...
if (ereg("^Mozilla\\/", $agent) || ereg("^Opera\\/", $agent) || ereg("^Links ", $agent) || ereg("^Lynx\\/", $agent))
{
header("HTTP/1.0 500 Bad Request");
die("This a a bittorrent application and can't be loaded into a browser");
}
// check if al needed information is sent by the client
if (!isset($_GET["port"]) || !isset($_GET["downloaded"]) || !isset($_GET["uploaded"]) || !isset($_GET["left"]))
show_error("Invalid information received from BitTorrent client");
$port = $_GET["port"];
$ip = mysql_escape_string(str_replace("::ffff:", "", $_SERVER["REMOTE_ADDR"]));
// IP Banned ?? -> thank you to stunnabbz for post bug on sf.net
$nip = ip2long($ip);
$res = mysql_query("SELECT * FROM bannedip WHERE $nip >= first AND $nip <= last") or error_log(__FILE__." - ".__LINE__);
if (mysql_num_rows($res) > 0)
{
show_error("You are not authorized to use this tracker (".$SITENAME.") -- Your IP address (".$ip.") is BANNED.");
die();
}
// end banned IP
$downloaded = floatval($_GET["downloaded"]);
$uploaded = floatval($_GET["uploaded"]);
$left = $_GET["left"];
$pid = AddSlashes($pid);
// if private announce turned on and PID empty string or not send by client
if (($pid=="" || !$pid) && $PRIVATE_ANNOUNCE)
show_error("Please redownload the torrent. PID system is active and pid was not found in the torrent");
// PID turned on
if ($PRIVATE_ANNOUNCE) {
$respid = mysql_query("SELECT users.*, level, can_download, WT FROM users INNER JOIN users_level on users.id_level=users_level.id WHERE pid='".$pid."' LIMIT 1");
if (!$respid || mysql_num_rows($respid)!=1)
show_error("Invalid PID (private announce): $pid. Please redownload torrent from $BASEURL.");
else
{
$rowpid=mysql_fetch_array($respid);
if ($rowpid["can_download"]!="yes" && $PRIVATE_ANNOUNCE)
show_error("Sorry your level ($rowpid[level]) is not allowed to download from $BASEURL.");
//waittime
elseif ($rowpid["WT"]>0) {
$wait=0;
if (intval($rowpid['downloaded'])>0) $ratio=number_format($rowpid['uploaded']/$rowpid['downloaded'],2);
else $ratio=0.0;
$res2 =mysql_query("SELECT UNIX_TIMESTAMP(data) as data, uploader FROM namemap WHERE info_hash='".$info_hash."'");
$added=mysql_fetch_array($res2);
$vz = $added["data"];
$timer = floor((time() - $vz) / 3600);
if($ratio<1.0 && $rowpid['id']!=$added["uploader"]){
$wait=$rowpid["WT"];
}
$wait -=$timer;
if ($wait<=0)$wait=0;
elseif($wait!=0 && $left!=0){show_error($rowpid["username"]." your Waiting Time = ".$wait." h");}
}
//end
}
} else {
// PID turned off
$respid = mysql_query("SELECT users.*, level, can_download, WT FROM users INNER JOIN users_level on users.id_level=users_level.id WHERE users.cip='$ip' LIMIT 1");
if (!$respid || mysql_num_rows($respid)!=1)
// maybe it's guest with new query I must found at least guest user
$respid = mysql_query("SELECT users.*, level, can_download, WT FROM users INNER JOIN users_level on users.id_level=users_level.id WHERE users.id_level=1 LIMIT 1");
if (!$respid || mysql_num_rows($respid)!=1)
{
// do nothing but tracker is misconfigured!!!
// guest user not found...
}
else
{
$rowpid=mysql_fetch_array($respid);
if ($rowpid["can_download"]!="yes")
show_error("Sorry your level ($rowpid[level]) is not allowed to download from $BASEURL.");
//waittime
elseif ($rowpid["WT"]>0) {
$wait=0;
if (intval($rowpid['downloaded'])>0) $ratio=number_format($rowpid['uploaded']/$rowpid['downloaded'],2);
else $ratio=0.0;
$res2 =mysql_query("SELECT UNIX_TIMESTAMP(data) as data, uploader FROM namemap WHERE info_hash='".$info_hash."'");
$added=mysql_fetch_array($res2);
$vz = $added["data"];
$timer = floor((time() - $vz) / 3600);
if($ratio<1.0 && $rowpid['id']!=$added["uploader"]){
$wait=$rowpid["WT"];
}
$wait -=$timer;
if ($wait<=0)
$wait=0;
elseif($wait!=0 && $left!=0)
{show_error($rowpid["username"]." your Waiting Time = ".$wait." h");}
}
//end
}
}
if (isset($_GET["event"]))
$event = $_GET["event"];
else
$event = "";
if (!isset($GLOBALS["ip_override"]))
$GLOBALS["ip_override"] = true;
if (isset($_GET["numwant"]))
if ($_GET["numwant"] < $GLOBALS["maxpeers"] && $_GET["numwant"] >= 0)
$GLOBALS["maxpeers"]=$_GET["numwant"];
if (isset($_GET["trackerid"]))
{
if (is_numeric($_GET["trackerid"]))
$GLOBALS["trackerid"] = mysql_escape_string($_GET["trackerid"]);
}
if (!is_numeric($port) || !is_numeric($downloaded) || !is_numeric($uploaded) || !is_numeric($left))
show_error("Invalid numerical field(s) from client");
/////////////////////////////////////////////////////
// Checks
// Upgrade holdover: check for unset directives
if (!isset($GLOBALS["countbytes"]))
$GLOBALS["countbytes"] = true;
if (!isset($GLOBALS["peercaching"]))
$GLOBALS["peercaching"] = 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;
}
// 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 show_error("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("Tracker error: 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("Tracker error: invalid torrent");
$data = mysql_fetch_assoc($results);
$GLOBALS["trackerid"] = $data["sequence"];
}
if (!($data))
return false;
return $data;
}
/////////////////////////////////////////////////////
// Any section of code might need to make a new peer, so this is a function here.
// I don't want to put it into funcsv2, even though it should, just for consistency's sake.
function start($info_hash, $ip, $port, $peer_id, $left, $downloaded=0, $uploaded=0, $upid="")
{
global $BASEURL;
if (isset($_GET["ip"]) && $GLOBALS["ip_override"])
{
// compact check: valid IP address:
if ($_GET["ip"]!=long2ip(ip2long($_GET["ip"])))
showError("Invalid IP address. Must be standard dotted decimal (hostnames not allowed)");
$ip = mysql_escape_string($_GET["ip"]);
}
else $ip = getip();
$ip = mysql_escape_string($ip);
$agent = mysql_escape_string($_SERVER["HTTP_USER_AGENT"]);
$remotedns = gethostbyaddr($ip);
if (isset($_GET["ip"])) $nuIP = $_GET["ip"];
else $nuIP = "";
if ($remotedns == $nuIP)
$remotedns = "AA";
else
{
$remotedns = strtoupper($remotedns);
preg_match('/^(.+)\.([A-Z]{2,3})$/', $remotedns, $tldm);
if (!empty($tldm[2]))
$remotedns = mysql_escape_string($tldm[2]);
else
$remotedns = "AA";
}
if ($left == 0)
$status = "seeder";
else
$status = "leecher";
if (@isFireWalled($info_hash, $peer_id, $ip, $port))
$nat = "Y";
else
$nat = "N";
$compact = mysql_escape_string(pack('Nn', ip2long($ip), $port));
$peerid = mysql_escape_string('2:ip' . strlen($ip) . ':' . $ip . '7:peer id20:' . hex2bin($peer_id) . "4:porti{$port}e");
$no_peerid = mysql_escape_string('2:ip' . strlen($ip) . ':' . $ip . "4:porti{$port}e");
$results = @mysql_query("INSERT INTO peers SET infohash=\"$info_hash\", peer_id=\"$peer_id\", port=\"$port\", ip=\"$ip\", lastupdate=UNIX_TIMESTAMP(), bytes=\"$left\", status=\"$status\", natuser=\"$nat\", client=\"$agent\", dns=\"$remotedns\", downloaded=$downloaded, uploaded=$uploaded, pid=\"$upid\"");
// Special case: duplicated peer_id.
if (!$results)
{
if (mysql_errno()==1062)
{
// Duplicate peer_id! Check IP address
$peer = getPeerInfo($peer_id, $info_hash);
if ($ip == $peer["ip"])
{
// Same IP address. Tolerate this error.
return "WHERE natuser='N'";
}
// Different IP address. Assume they were disconnected, and alter the IP address.
quickQuery("UPDATE peers SET ip=\"$ip\", compact=\"$compact\", with_peerid=\"$peerid\", without_peerid=\"$no_peerid\" WHERE peer_id=\"$peer_id\" AND infohash=\"$info_hash\"");
return "WHERE natuser='N'";
}
error_log("BtiTracker: start: ".mysql_error());
show_error("Tracker/database error. The details are in the error log.");
}
$GLOBALS["trackerid"] = mysql_insert_id();
@mysql_query("UPDATE peers SET sequence=\"${GLOBALS["trackerid"]}\", compact=\"$compact\", with_peerid=\"$peerid\", without_peerid=\"$no_peerid\" WHERE peer_id=\"$peer_id\" AND infohash=\"$info_hash\"");
if ($left == 0)
{
summaryAdd("seeds", 1);
return "WHERE status=\"leecher\" AND natuser='N'";
}
else
{
summaryAdd("leechers", 1);
return "WHERE natuser='N'";
}
}
/// End of function start
// default for max peers with same pid/ip
if (!isset($GLOBALS["maxseeds"])) $GLOBALS["maxseeds"]=2;
if (!isset($GLOBALS["maxleech"])) $GLOBALS["maxleech"]=2;
//
// 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;
}
// 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;
}
// 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:porti".$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)
{
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";
$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";
mysql_free_result($result);
}
// 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 = bcsub($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 ($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);
summaryAdd("lastcycle", "UNIX_TIMESTAMP()", true);
}
}
// 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 = bcsub($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);
}
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));
}
//
// select how many users with same
$results = mysql_query("SELECT status, count(status) FROM peers WHERE ".($PRIVATE_ANNOUNCE?"pid=\"$pid\"":"ip=\"$ip\"")." AND infohash=\"$info_hash\" AND peer_id<>\"$peer_id\" GROUP BY status") or show_error("Tracker error: invalid torrent");
$status = array();
while ($resstat = mysql_fetch_row($results))
$status[$resstat[0]]=$resstat[1];
if (!isset($status["leecher"]))
$status["leecher"]=0;
if (!isset($status["seeder"]))
$status["seeder"]=0;
if ($status["seeder"]>=$GLOBALS["maxseeds"] || $status["leecher"]>=$GLOBALS["maxleech"])
show_error("Sorry max peers reached! Redownload torrent from $BASEURL");
// end select
// UPDATE users ratio down/up for every event on every announce
// only with the difference between stored down/up and sended by client
if ($LIVESTATS)
{
$resstat=mysql_query("SELECT uploaded, downloaded FROM peers WHERE peer_id=\"$peer_id\" AND infohash=\"$info_hash\"");
if ($resstat && mysql_num_rows($resstat)>0)
{
$livestat=mysql_fetch_array($resstat);
// only if uploaded/downloaded are >= stored data in peer list
if ($uploaded>=$livestat["uploaded"])
$newup=($uploaded-$livestat["uploaded"]);
else
$newup=$uploaded;
if ($downloaded>=$livestat["downloaded"])
$newdown=($downloaded-$livestat["downloaded"]);
else
$newdown=$downloaded;
quickquery("UPDATE users SET downloaded=IFNULL(downloaded,0)+$newdown, uploaded=IFNULL(uploaded,0)+$newup WHERE ".($PRIVATE_ANNOUNCE?"pid='$pid'":"cip='$ip'")."");
}
mysql_free_result($resstat);
// begin history - also this is registred live or not
if ($LOG_HISTORY)
{
$resu=mysql_query("SELECT id FROM users WHERE ".($PRIVATE_ANNOUNCE?"pid='$pid'":"cip='$ip'") ." ORDER BY lastconnect DESC LIMIT 1");
// if found at least one user should be 1
if ($resu && mysql_num_rows($resu)==1)
{
$curuid=mysql_fetch_array($resu);
quickQuery("UPDATE history set uploaded=IFNULL(uploaded,0)+$newup, downloaded=IFNULL(downloaded,0)+$newdown WHERE uid=".$curuid["id"]." AND infohash='$info_hash'");
}
mysql_free_result($resu);
}
// end history }
}
switch ($event)
{
// client sent start
case "started":
verifyTorrent($info_hash) or show_error("Torrent is not authorized for use on this tracker.");
$start = start($info_hash, $ip, $port, $peer_id, $left, $downloaded, $uploaded, $pid);
if ($GLOBALS["peercaching"])
sendRandomPeers($info_hash);
else
{
$peers = getRandomPeers($info_hash, "");
sendPeerList($peers);
}
// begin history
if ($LOG_HISTORY)
{
$resu=mysql_query("SELECT id FROM users WHERE ".($PRIVATE_ANNOUNCE?"pid='$pid'":"cip='$ip'") ." ORDER BY lastconnect DESC LIMIT 1");
// if found at least one user should be 1
if ($resu && mysql_num_rows($resu)==1)
{
$curuid=mysql_fetch_array($resu);
quickQuery("UPDATE history set active='yes',agent='".getagent($agent,$peer_id)."' WHERE uid=".$curuid["id"]." AND infohash='$info_hash'");
// record is not present, create it (only if not seeder: original seeder don't exist in history table, other already exists)
if (mysql_affected_rows()==0 && $left>0)
quickQuery("INSERT INTO history (uid,infohash,active,agent) VALUES (".$curuid["id"].",'$info_hash','yes','".getagent($agent,$peer_id)."')");
}
mysql_free_result($resu);
}
// end history
break;
// client sent stop
case "stopped":
verifyTorrent($info_hash) or show_error("Torrent is not authorized for use on this tracker.");
killPeer($peer_id, $info_hash, $left);
// I don't know why, but the real tracker returns peers on event=stopped
// but I'll just send an empty list. On the other hand,
// TheSHADOW asked for this.
if (isset($_GET["tracker"]))
$peers = getRandomPeers($info_hash);
else
$peers = array("size" => 0);
sendPeerList($peers);
// update user uploaded/downloaded
if (!$LIVESTATS)
@mysql_query("UPDATE users SET uploaded=IFNULL(uploaded,0)+$uploaded, downloaded=IFNULL(downloaded,0)+$downloaded WHERE ".($PRIVATE_ANNOUNCE?"pid='$pid'":"cip='$ip'")." AND id>1 LIMIT 1");
// begin history - if LIVESTAT, only the active/agent part
if ($LOG_HISTORY)
{
$resu=mysql_query("SELECT id FROM users WHERE ".($PRIVATE_ANNOUNCE?"pid='$pid'":"cip='$ip'") ." ORDER BY lastconnect DESC LIMIT 1");
// if found at least one user should be 1
if ($resu && mysql_num_rows($resu)==1)
{
$curuid=mysql_fetch_array($resu);
quickQuery("UPDATE history set active='no',".($LIVESTATS?"":" uploaded=IFNULL(uploaded,0)+$uploaded, downloaded=IFNULL(downloaded,0)+$downloaded,")." agent='".getagent($agent,$peer_id)."' WHERE uid=".$curuid["id"]." AND infohash='$info_hash'");
}
mysql_free_result($resu);
}
// end history }
break;
// client sent complete
case "completed":
verifyTorrent($info_hash) or show_error("Torrent is not authorized for use on this tracker.");
$peer_exists = getPeerInfo($peer_id, $info_hash);
if (!is_array($peer_exists))
start($info_hash, $ip, $port, $peer_id, $left, $downloaded, $uploaded, $pid);
else
{
quickQuery("UPDATE peers SET bytes=0, status=\"seeder\" WHERE sequence=\"${GLOBALS["trackerid"]}\" AND infohash=\"$info_hash\"");
// Race check
if (mysql_affected_rows() == 1)
{
summaryAdd("leechers", -1);
summaryAdd("seeds", 1);
summaryAdd("finished", 1);
summaryAdd("lastcycle", "UNIX_TIMESTAMP()", true);
}
}
collectBytes($peer_exists, $info_hash, $left, $downloaded, $uploaded, $pid);
$peers=getRandomPeers($info_hash);
sendPeerList($peers);
// begin history
if ($LOG_HISTORY)
{
$resu=mysql_query("SELECT id FROM users WHERE ".($PRIVATE_ANNOUNCE?"pid='$pid'":"cip='$ip'") ." ORDER BY lastconnect DESC LIMIT 1");
// if found at least one user should be 1
if ($resu && mysql_num_rows($resu)==1)
{
$curuid=mysql_fetch_array($resu);
// if user has already completed this torrent, mysql will give error because of unique index (uid+infohash)
// upload/download will be updated on stop event...
// record should already exist (created on stated event)
quickQuery("UPDATE history SET date=UNIX_TIMESTAMP(),active='yes',agent='".getagent($agent,$peer_id)."' WHERE uid=".$curuid["id"]." AND infohash='$info_hash'");
// record is not present, create it
if (mysql_affected_rows()==0)
quickQuery("INSERT INTO history (uid,infohash,date,active,agent) VALUES (".$curuid["id"].",'$info_hash',UNIX_TIMESTAMP(),'yes','".getagent($agent,$peer_id)."')");
}
mysql_free_result($resu);
}
// end history
break;
// client sent no event
case "":
verifyTorrent($info_hash) or show_error("Torrent is not authorized for use on this tracker.");
$peer_exists = getPeerInfo($peer_id, $info_hash);
$where = "WHERE natuser='N'";
if (!is_array($peer_exists))
$where = start($info_hash, $ip, $port, $peer_id, $left, $downloaded, $uploaded, $pid);
if ($peer_exists["bytes"] != 0 && $left == 0)
{
quickQuery("UPDATE peers SET bytes=0, status=\"seeder\" WHERE sequence=\"${GLOBALS["trackerid"]}\" AND infohash=\"$info_hash\"");
if (mysql_affected_rows() == 1)
{
summaryAdd("leechers", -1);
summaryAdd("seeds", 1);
summaryAdd("finished", 1);
summaryAdd("lastcycle", "UNIX_TIMESTAMP()", true);
}
}
collectBytes($peer_exists, $info_hash, $left, $downloaded, $uploaded, $pid);
if ($GLOBALS["peercaching"])
sendRandomPeers($info_hash);
else
{
$peers = getRandomPeers($info_hash, "");
sendPeerList($peers);
}
break;
// not valid event
default:
show_error("Invalid event= from client.");
}
if ($GLOBALS["countbytes"])
{
// Once every minute or so, we run the speed update checker.
$query = @mysql_query("SELECT UNIX_TIMESTAMP() - lastSpeedCycle FROM summary WHERE info_hash=\"$info_hash\"");
$results = mysql_fetch_row($query);
if ($results[0] >= 60)
@runSpeed($info_hash, $results[0]);
}
// Finally, it's time to do stuff to the summary table.
if (!empty($summaryupdate))
{
$stuff = "";
foreach ($summaryupdate as $column => $value)
{
$stuff .= ', '.$column. ($value[1] ? "=" : "=$column+") . $value[0];
}
mysql_query("UPDATE summary SET ".substr($stuff, 1)." WHERE info_hash=\"$info_hash\"");
}
// generaly not needed, but
// just in case server don't close connection
mysql_close();
?>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 verifyTorrent($hash)
{
return true;
}ALTER TABLE namemap CHANGE external external ENUM('yes','no') DEFAULT 'no';
UPDATE namemap SET external='no';
?>if ($_GET['update']==1)
{
include '../include/functions.php';
dbconn(true);
do_sanity();
echo 'update OK';
}Użytkownicy przeglądający to forum: Brak zalogowanych użytkowników i 0 gości