Browse code

Checks added to some files: torrent_functions.php, tracker.php dltorrent.php's check changed to authenticate no matter what Some fixes and modifications from 2014: index.php, funcsv2.php, batch_upload.php, newtorrents.php, install.php, editconfig.php Version bumped up to 1.05

Clarissa Walker authored on 2015/08/30 00:06:28
Showing 1 changed files
... ...
@@ -363,6 +363,13 @@ function sendRandomPeers($info_hash)
363 363
 			echo str_pad($row[0], 6, chr(32));
364 364
 	}
365 365
 	else
366
+	if ($column == "compact")
367
+	{
368
+		echo (mysql_num_rows($result) * 18) . ":";
369
+		while ($row = mysql_fetch_row($result))
370
+			echo str_pad($row[0], 18, chr(32));
371
+	}
372
+	else
366 373
 	{
367 374
 		echo "l";
368 375
 		while ($row = mysql_fetch_row($result))
Browse code

Import from the old rivettracker git repository at sourceforge (amisaph/amisapphire branch)

Clarissa Walker (ami-sapphire) authored on 2014/01/24 14:02:23
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,678 @@
1
+<?php
2
+
3
+
4
+//////////////////////////////////////////////////////////////////
5
+// Worker functions
6
+
7
+if (function_exists("bcadd"))
8
+{
9
+	function sqlAdd($left, $right)
10
+	{
11
+		return bcadd($left, $right,0);
12
+	}
13
+	function sqlSubtract($left, $right)
14
+	{
15
+		return bcsub($left, $right,0);
16
+	}
17
+	function sqlMultiply($left, $right)
18
+	{
19
+		return bcmul($left, $right,0);
20
+	}
21
+	function sqlDivide($left, $right)
22
+	{
23
+		return bcdiv($left, $right,0);
24
+	}
25
+}
26
+else // BC vs SQL math
27
+{
28
+
29
+// Uses the mysql database connection to perform string math. :)
30
+// Used by byte counting functions
31
+// No error handling as we assume nothing can go wrong. :|
32
+function sqlAdd($left, $right)
33
+{
34
+	$query = 'SELECT '.$left.'+'.$right;
35
+	$results = mysql_query($query) or showError("Database error.");
36
+	return mysql_result($results,0,0);
37
+}
38
+
39
+// Ditto
40
+function sqlSubtract($left, $right)
41
+{
42
+	$query = 'SELECT '.$left.'-'.$right;
43
+	$results = mysql_query($query) or showError("Database error");
44
+	return mysql_result($results,0,0);
45
+}
46
+
47
+function sqlDivide($left, $right)
48
+{
49
+	$query = 'SELECT '.$left.'/'.$right;
50
+	$results = mysql_query($query) or showError("Database error");
51
+	return mysql_result($results,0,0);
52
+}
53
+
54
+function sqlMultiply($left, $right)
55
+{
56
+	$query = 'SELECT '.$left.'*'.$right;
57
+	$results = mysql_query($query) or showError("Database error");
58
+	return mysql_result($results,0,0);
59
+}
60
+
61
+
62
+} // End of BC vs SQL
63
+
64
+// Runs a query with no regard for the result
65
+function quickQuery($query)
66
+{
67
+	$results = @mysql_query($query);
68
+	if (!is_bool($results))
69
+		mysql_free_result($results);
70
+	else
71
+		return $results;
72
+	return true;
73
+}
74
+
75
+if(!function_exists('hex2bin'))
76
+{
77
+	function hex2bin ($input, $assume_safe=true)
78
+	{
79
+		if ($assume_safe !== true && ! ((strlen($input) % 2) === 0 || preg_match ('/^[0-9a-f]+$/i', $input)))
80
+			return "";
81
+		return pack('H*', $input );
82
+	}
83
+}
84
+
85
+// Reports an error to the client in $message.
86
+// Any other output will confuse the client, so please don't do that.
87
+function showError($message, $log=false)
88
+{
89
+  if ($log)
90
+	  error_log("RivetTracker: Sent error ($message)");
91
+  echo "d14:failure reason".strlen($message).":$message"."e";
92
+  exit(0);
93
+}
94
+
95
+
96
+function errorMessage()
97
+{
98
+	echo "<center><img src='images/important.png' border='0' class='icon' alt='Critical Message' title='Critical Message' /></center>\n<p class='error'>";
99
+}
100
+
101
+
102
+
103
+// Used by newtorrents.php
104
+// Returns true/false, depending on if there were errors.
105
+function makeTorrent($hash, $tolerate = false)
106
+{
107
+	require("config.php"); //necessary to get the prefix value, require_once() doesn't seem to work :/
108
+	if (strlen($hash) != 40)
109
+		showError("makeTorrent: Received an invalid hash");
110
+	$result = true;
111
+	$query = "CREATE TABLE ".$prefix."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', primary key(sequence), unique(peer_id)) DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci ENGINE = innodb";
112
+	if (!@mysql_query($query))
113
+		$result = false;
114
+	if (!$result && !$tolerate)
115
+		return false;
116
+	//peercaching is ALWAYS on
117
+	$query = "CREATE TABLE ".$prefix."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 DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci ENGINE = innodb";
118
+	mysql_query($query);
119
+		
120
+	$query = "INSERT INTO ".$prefix."summary set info_hash='".$hash."', lastSpeedCycle=UNIX_TIMESTAMP()";
121
+	if (!@mysql_query($query))
122
+		$result = false;
123
+	return $result;
124
+}
125
+
126
+// Returns true if the torrent exists.
127
+// Currently checks by locating the row in "summary"
128
+function verifyTorrent($hash)
129
+{
130
+	require("config.php"); //need prefix value...
131
+	$query = "SELECT COUNT(*) FROM ".$prefix."summary where info_hash='$hash'";
132
+	$results = mysql_query($query);
133
+	
134
+	$res = mysql_result($results,0,0);
135
+	
136
+	if ($res == 1)
137
+		return true;
138
+
139
+	return false;
140
+}
141
+
142
+function verifyHash($input)
143
+{
144
+	if (strlen($input) === 40 && preg_match('/^[0-9a-f]+$/', $input))
145
+		return true;
146
+	else
147
+		return false;
148
+}
149
+
150
+
151
+
152
+
153
+// Returns info on one peer
154
+function getPeerInfo($user, $hash)
155
+{
156
+	require("config.php");
157
+	// If "trackerid" is set, let's try that
158
+	if (isset($GLOBALS["trackerid"]))
159
+	{
160
+		$query = "SELECT peer_id,bytes,ip,port,status,lastupdate,sequence FROM ".$prefix."x$hash WHERE sequence=${GLOBALS["trackerid"]}";
161
+		$results = mysql_query($query) or showError("Tracker error: invalid torrent");
162
+		$data = mysql_fetch_assoc($results);
163
+		if (!$data || $data["peer_id"] != $user)
164
+		{
165
+			// Damn, but don't crash just yet.
166
+			$query = "SELECT peer_id,bytes,ip,port,status,lastupdate,sequence FROM ".$prefix."x$hash WHERE peer_id='$user'";
167
+			$results = mysql_query($query) or showError("Tracker error: invalid torrent"); 
168
+			$data = mysql_fetch_assoc($results);
169
+			$GLOBALS["trackerid"] = $data["sequence"];
170
+		}
171
+	}
172
+	else
173
+	{
174
+		$query = "SELECT peer_id,bytes,ip,port,status,lastupdate,sequence FROM ".$prefix."x$hash WHERE peer_id='$user'";
175
+		$results = mysql_query($query) or showError("Tracker error: invalid torrent");
176
+		$data = mysql_fetch_assoc($results);
177
+		$GLOBALS["trackerid"] = $data["sequence"];
178
+
179
+	}
180
+	
181
+	if (!($data))
182
+		return false;
183
+	
184
+	return $data;
185
+}
186
+
187
+// Slight redesign of loadPeers
188
+function getRandomPeers($hash, $where="")
189
+{
190
+	require("config.php");
191
+
192
+	// Don't want to send a bad "num peers" for new seeds
193
+	if ($GLOBALS["NAT"])
194
+		$results = mysql_query("SELECT COUNT(*) FROM ".$prefix."x$hash WHERE natuser = 'N'");
195
+	else
196
+		$results = mysql_query("SELECT COUNT(*) FROM ".$prefix."x$hash");
197
+
198
+	$peercount = mysql_result($results, 0,0);
199
+
200
+	// ORDER BY RAND() is expensive. Don't do it when the load gets too high
201
+	if ($peercount < 500)
202
+		$query = "SELECT ".((isset($_GET["no_peer_id"]) && $_GET["no_peer_id"] == 1) ? "" : "peer_id,")."ip, port, status FROM ".$prefix."x$hash ".$where." ORDER BY RAND() LIMIT ${GLOBALS['maxpeers']}";
203
+	else
204
+		$query = "SELECT ".((isset($_GET["no_peer_id"]) && $_GET["no_peer_id"] == 1) ? "" : "peer_id,")."ip, port, status FROM ".$prefix."x$hash LIMIT ".@mt_rand(0, $peercount - $GLOBALS["maxpeers"]).", ${GLOBALS['maxpeers']}";
205
+
206
+	$results = mysql_query($query);
207
+	if (!$results)
208
+		return false;
209
+
210
+	$peerno = 0;
211
+	while ($return[] = mysql_fetch_assoc($results))
212
+		$peerno++;
213
+
214
+	array_pop ($return);
215
+	mysql_free_result($results);
216
+	$return['size'] = $peerno;
217
+ 
218
+	return $return;
219
+}
220
+	
221
+//  Deletes a peer from the system and performs all cleaning up
222
+//
223
+//  $assumepeer contains the result of getPeerInfo, or false
224
+//  if we should grab it ourselves.
225
+function killPeer($userid, $hash, $left, $assumepeer = false)
226
+{
227
+	require("config.php");
228
+	if (!$assumepeer)
229
+	{
230
+		$peer = getPeerInfo($userid, $hash);
231
+		if (!$peer)
232
+			return;
233
+		if ($left != $peer["bytes"])
234
+			$bytes = sqlSubtract($peer["bytes"], $left);
235
+		else
236
+			$bytes = 0;
237
+	}
238
+	else
239
+	{
240
+		$bytes = 0;
241
+		$peer = $assumepeer;
242
+	}
243
+
244
+	quickQuery("DELETE FROM ".$prefix."x$hash WHERE peer_id='$userid'");
245
+	if (mysql_affected_rows() == 1)
246
+	{
247
+		//peercaching ALWAYS on
248
+		quickQuery("DELETE FROM ".$prefix."y$hash WHERE sequence=" . $peer["sequence"]);
249
+		if ($peer["status"] == "leecher")
250
+			summaryAdd("leechers", -1);
251
+		else
252
+			summaryAdd("seeds", -1);
253
+		if ($GLOBALS["countbytes"] && ((float)$bytes) > 0)
254
+			summaryAdd("dlbytes",$bytes);
255
+		if ($peer["bytes"] != 0 && $left == 0)
256
+			summaryAdd("finished", 1);
257
+	}
258
+}
259
+
260
+// Transfers bytes from "left" to "dlbytes" when a peer reports in.
261
+function collectBytes($peer, $hash, $left)
262
+{
263
+	require("config.php");
264
+	$peerid=$peer["peer_id"];
265
+
266
+	if (!$GLOBALS["countbytes"])
267
+	{
268
+		quickQuery("UPDATE ".$prefix."x$hash SET lastupdate=UNIX_TIMESTAMP() where " . (isset($GLOBALS["trackerid"]) ? "sequence='${GLOBALS["trackerid"]}'" : "peer_id='$peerid'"));
269
+		return;
270
+	}
271
+	$diff = sqlSubtract($peer["bytes"], $left);
272
+	quickQuery("UPDATE ".$prefix."x$hash set " . (($diff != 0) ? "bytes='$left'," : ""). " lastupdate=UNIX_TIMESTAMP() where " . (isset($GLOBALS["trackerid"]) ? "sequence='${GLOBALS["trackerid"]}'" : "peer_id='$peerid'"));
273
+
274
+
275
+	// Anti-negative clause
276
+	if (((float)$diff) > 0)
277
+		summaryAdd("dlbytes", $diff);
278
+}
279
+
280
+// Transmits the actual data to the peer. No other output is permitted if
281
+// this function is called, as that would break BEncoding.
282
+// I don't use the bencode library, so watch out! If you add data,
283
+// rules such as dictionary sorting are enforced by the remote side.
284
+function sendPeerList($peers)
285
+{
286
+	echo "d";
287
+  	echo "8:intervali".$GLOBALS["report_interval"]."e";
288
+	if (isset($GLOBALS["min_interval"]))
289
+		echo "12:min intervali".$GLOBALS["min_interval"]."e";
290
+	echo "5:peers";
291
+	$size=$peers["size"];
292
+	if (isset($_GET["compact"]) && $_GET["compact"] == '1')
293
+	{
294
+		$p = '';
295
+		for ($i=0; $i < $size; $i++)
296
+			$p .= pack("Nn", ip2long($peers[$i]['ip']), $peers[$i]['port']);
297
+		echo strlen($p).':'.$p;
298
+	}
299
+	else // no_peer_id or no feature supported
300
+	{
301
+		echo 'l';
302
+		for ($i=0; $i < $size; $i++)
303
+		{
304
+			echo "d2:ip".strlen($peers[$i]["ip"]).":".$peers[$i]["ip"];
305
+			if (isset($peers[$i]["peer_id"]))
306
+				echo "7:peer id20:".hex2bin($peers[$i]["peer_id"]);
307
+			echo "4:porti".$peers[$i]["port"]."ee";
308
+		}
309
+		echo "e";
310
+	}
311
+	if (isset($GLOBALS["trackerid"]))
312
+	{
313
+		// Now it gets annoying. trackerid is a string
314
+		echo "10:tracker id".strlen($GLOBALS["trackerid"]).":".$GLOBALS["trackerid"];
315
+	}
316
+
317
+	echo "e";
318
+}
319
+
320
+
321
+// Faster pass-through version of getRandompeers => sendPeerList
322
+// It's the only way to use cache tables. In fact, it only uses it.
323
+function sendRandomPeers($info_hash)
324
+{
325
+	require("config.php");
326
+	$result = mysql_query("SELECT COUNT(*) FROM ".$prefix."y$info_hash");
327
+	$count = mysql_result($result, 0, 0);
328
+	
329
+	if (isset($_GET["compact"]) && $_GET["compact"] == '1')
330
+		$column = "compact";
331
+	else if (isset($_GET["no_peer_id"]) && $_GET["no_peer_id"] == '1')
332
+		$column = "without_peerid";
333
+	else
334
+		$column = "with_peerid";
335
+	
336
+	if ($count < $GLOBALS["maxpeers"])
337
+		$query = "SELECT $column FROM ".$prefix."y$info_hash";
338
+	else if ($count > 500)
339
+	{
340
+		do
341
+		{
342
+			$rand1 = mt_rand(0, $count-$GLOBALS["maxpeers"]);
343
+			$rand2 = mt_rand(0, $count-$GLOBALS["maxpeers"]);
344
+		} while (abs($rand1 - $rand2) < $GLOBALS["maxpeers"]/2);
345
+		$query = "(SELECT $column FROM ".$prefix."y$info_hash LIMIT $rand1, ".($GLOBALS["maxpeers"]/2). ") UNION (SELECT $column FROM ".$prefix."y$info_hash LIMIT $rand2, ".($GLOBALS["maxpeers"]/2). ")";
346
+	}
347
+	else
348
+		$query = "SELECT $column FROM ".$prefix."y$info_hash ORDER BY RAND() LIMIT ".$GLOBALS["maxpeers"];
349
+
350
+	
351
+
352
+	echo "d";
353
+  	echo "8:intervali".$GLOBALS["report_interval"]."e";
354
+	if (isset($GLOBALS["min_interval"]))
355
+		echo "12:min intervali".$GLOBALS["min_interval"]."e";
356
+	echo "5:peers";
357
+
358
+	$result = mysql_query($query);
359
+	if ($column == "compact")
360
+	{
361
+		echo (mysql_num_rows($result) * 6) . ":";
362
+		while ($row = mysql_fetch_row($result))
363
+			echo str_pad($row[0], 6, chr(32));
364
+	}
365
+	else
366
+	{
367
+		echo "l";
368
+		while ($row = mysql_fetch_row($result))
369
+			echo "d".$row[0]."e";
370
+		echo "e";
371
+	}
372
+	if (isset($GLOBALS["trackerid"]))
373
+		echo "10:tracker id".strlen($GLOBALS["trackerid"]).":".$GLOBALS["trackerid"];
374
+	echo "e";
375
+}
376
+
377
+
378
+// Returns a $peers array of all peers that have timed out (2* report interval seems fair
379
+// for any reasonable report interval (900 or larger))
380
+function loadLostPeers($hash, $timeout)
381
+{
382
+	require("config.php"); //necessary for getting prefix value
383
+	$results = mysql_query("SELECT peer_id,bytes,ip,port,status,lastupdate,sequence from ".$prefix."x$hash where lastupdate < (UNIX_TIMESTAMP() - 2 * $timeout)");
384
+	$peerno = 0;
385
+	if (!$results)
386
+		return false;
387
+	
388
+	while ($return[] = mysql_fetch_assoc($results))
389
+		$peerno++;	
390
+	array_pop($return);
391
+	$return["size"] = $peerno;
392
+	mysql_free_result($results);
393
+	return $return;
394
+}
395
+
396
+function trashCollector($hash, $timeout)
397
+{
398
+	require("config.php"); //need to grab prefix value...
399
+	if (isset($GLOBALS["trackerid"]))
400
+		unset($GLOBALS["trackerid"]);
401
+
402
+	if (!Lock($hash))
403
+		return;
404
+	
405
+	$results = mysql_query("SELECT lastcycle FROM ".$prefix."summary WHERE info_hash='$hash'");
406
+	$lastcheck = (mysql_fetch_row($results));
407
+	
408
+	// Check once every re-announce cycle
409
+	if (($lastcheck[0] + $timeout) < time())
410
+	{
411
+		$peers = loadLostPeers($hash, $timeout);
412
+		for ($i=0; $i < $peers["size"]; $i++)
413
+			killPeer($peers[$i]["peer_id"], $hash, $peers[$i]["bytes"]);
414
+		summaryAdd("lastcycle", "UNIX_TIMESTAMP()", true);
415
+	}
416
+	Unlock($hash);
417
+}
418
+
419
+// Attempts to aquire a lock by name.
420
+// Returns true on success, false on failure
421
+function Lock($hash, $time = 0)
422
+{
423
+	$results = mysql_query("SELECT GET_LOCK('$hash', $time)");
424
+	$string = mysql_fetch_row($results);
425
+	if (strcmp($string[0], "1") == 0)
426
+		return true;
427
+	return false;
428
+
429
+}
430
+
431
+// Releases a lock. Ignores errors.
432
+function Unlock($hash)
433
+{
434
+	quickQuery("SELECT RELEASE_LOCK('$hash')");
435
+}
436
+
437
+// Returns true if the lock is available
438
+function isFreeLock($lock)
439
+{
440
+	if (Lock($lock, 0))
441
+	{
442
+		Unlock($lock);
443
+		return true;
444
+	}
445
+	return false;
446
+}
447
+
448
+
449
+/* Returns true if the user is firewalled, NAT'd, or whatever.
450
+ * The original tracker had its --nat_check parameter, so
451
+ * here is my version.
452
+ *
453
+ * This code has proven itself to be sufficiently correct,
454
+ * but will consume system resources when a lot of httpd processes
455
+ * are lingering around trying to connect to remote hosts.
456
+ * Consider disabling it under higher loads.
457
+ */
458
+function isFireWalled($hash, $peerid, $ip, $port)
459
+{
460
+
461
+	// NAT checking off?
462
+	if (!$GLOBALS["NAT"])
463
+		return false;
464
+
465
+	$protocol_name = 'BitTorrent protocol';
466
+	$theError = "";
467
+	// Hoping 10 seconds will be enough
468
+	$fd = fsockopen($ip, $port, $errno, $theError, 10);
469
+	if (!$fd)
470
+		return true;
471
+
472
+	stream_set_timeout($fd, 5, 0);
473
+	fwrite($fd, chr(strlen($protocol_name)).$protocol_name.hex2bin("0000000000000000").
474
+		hex2bin($hash));
475
+	
476
+	$data = fread($fd, strlen($protocol_name)+1+20+20+8); // ideally...
477
+
478
+	fclose($fd);
479
+	$offset = 0;
480
+
481
+	// First byte: strlen($protocol_name), then the protocol string itself
482
+	if (ord($data[$offset]) != strlen($protocol_name))
483
+		return true;
484
+
485
+	$offset++;
486
+	if (substr($data, $offset, strlen($protocol_name)) != $protocol_name)
487
+		return true;
488
+
489
+	$offset += strlen($protocol_name);
490
+	// 8 bytes reserved, ignore
491
+	$offset += 8;
492
+	
493
+	// Download ID (hash)
494
+	if (substr($data, $offset, 20) != hex2bin($hash))
495
+		return true;
496
+
497
+	$offset+=20;
498
+	
499
+	// Peer ID
500
+	if (substr($data, $offset, 20) != hex2bin($peerid))
501
+		return true;
502
+
503
+	
504
+	return false;
505
+}
506
+
507
+
508
+// It's cruel, but if people abuse my tracker, I just might do it.
509
+// It pretends to accept the torrent, and reports that you are the
510
+// only person connected.
511
+function evilReject($ip, $peer_id, $port)
512
+{
513
+
514
+	// For those of you who are feeling evil, comment out this line.
515
+	showError("Torrent is not authorized for use on this tracker.");
516
+
517
+	$peers[0]["peer_id"] = $peer_id;
518
+	$peers[0]["ip"] = $ip;
519
+	$peers[0]["port"] = $port;
520
+	$peers["size"] = 1;
521
+	$GLOBALS["report_interval"] = 86400;
522
+	$GLOBALS["min_interval"] = 86000;
523
+	sendPeerList($peers);
524
+	exit(0);
525
+}
526
+
527
+
528
+function runSpeed($info_hash, $delta)
529
+{
530
+	require("config.php");
531
+	//stick in our latest data before we calc it out
532
+	quickQuery("INSERT IGNORE INTO ".$prefix."timestamps (info_hash, bytes, delta, sequence) SELECT '$info_hash' AS info_hash, dlbytes, UNIX_TIMESTAMP() - lastSpeedCycle, NULL FROM ".$prefix."summary WHERE info_hash='$info_hash'");
533
+
534
+	// mysql blows sometimes so we have to read the data into php before updating it
535
+	$results = mysql_query('SELECT (MAX(bytes)-MIN(bytes))/SUM(delta), COUNT(*), MIN(sequence) FROM '.$prefix.'timestamps WHERE info_hash="'.$info_hash.'"' );
536
+	$data = mysql_fetch_row($results);
537
+	
538
+	$results2 = mysql_query('SELECT '.$prefix.'summary.leechers FROM '.$prefix.'summary WHERE info_hash="'.$info_hash.'"');
539
+	$data2 = mysql_fetch_row($results2);
540
+	if ($data2[0] == 0) //if no leechers, speed is zero
541
+		$data[0] = 0;
542
+		
543
+	$results3 = mysql_query("SELECT MIN(d1.bytes), MAX(d1.bytes) FROM (SELECT bytes FROM ".$prefix."timestamps WHERE info_hash='".$info_hash."' ORDER BY sequence DESC LIMIT 5) AS d1");
544
+	$data3 = mysql_fetch_row($results3);
545
+	//if the last 5 updates from clients show the same bytes, it's probably stalled, set speed to zero
546
+	if ($data3[0] == $data3[1])
547
+		$data[0] = 0;
548
+	
549
+	summaryAdd("speed", $data[0], true);
550
+	summaryAdd("lastSpeedCycle", "UNIX_TIMESTAMP()", true);
551
+
552
+	// if we have more than 20 drop the rest
553
+	//if ($data[1] == 21)
554
+		//quickQuery("DELETE FROM timestamps WHERE info_hash='$info_hash' AND sequence=${data[2]}");
555
+	if ($data[1] > 21)
556
+		// This query requires MySQL 4.0.x, but should rarely be used.
557
+		quickQuery ('DELETE FROM '.$prefix.'timestamps WHERE info_hash="'.$info_hash.'" ORDER BY sequence LIMIT '.($data['1'] - 20));
558
+}
559
+
560
+// Schedules an update to the summary table. It gets so much traffic
561
+// that we do all our changes at once.
562
+// When called, the column $column for the current info_hash is incremented
563
+// by $value, or set to exactly $value if $abs is true.
564
+function summaryAdd($column, $value, $abs = false)
565
+{
566
+	if (isset($GLOBALS["summaryupdate"][$column]))
567
+	{
568
+		if (!$abs)
569
+			$GLOBALS["summaryupdate"][$column][0] += $value;
570
+		else
571
+			showError("Tracker bug calling summaryAdd");
572
+	}
573
+	else
574
+	{
575
+		$GLOBALS["summaryupdate"][$column][0] = $value;
576
+		$GLOBALS["summaryupdate"][$column][1] = $abs;
577
+	}
578
+}
579
+
580
+
581
+//converts byte size to string format for display
582
+function bytesToString($total_size)
583
+{
584
+	if ($total_size < 1024) //dealing with bytes
585
+		return $total_size . " bytes";
586
+	elseif ($total_size < 1048576) //dealing with kilobytes
587
+		return round($total_size/1024, 2) . " KB";
588
+	elseif ($total_size < 1073741824) //dealing with megabytes
589
+		return round($total_size/1048576, 2) . " MB";
590
+	elseif ($total_size >= 1073741824) //dealing with gigabytes
591
+		return round($total_size/1073741824, 2) . " GB";
592
+}
593
+
594
+
595
+// Even if you're missing PHP 4.3.0, the MHASH extension might be of use.
596
+// Someone was kind enought to email this code snippit in.
597
+if (function_exists('mhash') && (!function_exists('sha1')) && 
598
+defined('MHASH_SHA1'))
599
+{
600
+	function sha1($str)
601
+	{
602
+		return bin2hex(mhash(MHASH_SHA1,$str));
603
+	}
604
+}
605
+
606
+//If magic quotes are on, returns the cleaned (no single quotes) output string
607
+function clean($input)
608
+{
609
+	if (get_magic_quotes_gpc())
610
+		return stripslashes($input);
611
+	return $input;
612
+}
613
+
614
+//If magic quotes are off, returns the added (single quotes) output string
615
+function addquotes($input)
616
+{
617
+	if (!get_magic_quotes_gpc())
618
+		return addslashes($input);
619
+	return $input;
620
+}
621
+
622
+//generic filter function for cleaning data
623
+function filterData($data)
624
+{
625
+	$data = trim(htmlentities(strip_tags($data)));
626
+
627
+	if (get_magic_quotes_gpc()) {
628
+		return stripslashes($data);
629
+	}
630
+
631
+	$data = mysql_real_escape_string($data);
632
+
633
+	return $data;
634
+}
635
+
636
+//generic filter function for character cleaning data
637
+function filterChar($data)
638
+{
639
+	$data = filter_var($data, FILTER_SANITIZE_FULL_SPECIAL_CHARS);
640
+
641
+	if (get_magic_quotes_gpc()) {
642
+		return stripslashes($data);
643
+	}
644
+
645
+	$data = mysql_real_escape_string($data);
646
+
647
+	return $data;
648
+}
649
+
650
+//generic filter function for validating integer and hex data
651
+function filterInt($data)
652
+{
653
+	$data = filter_var($data, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX);
654
+
655
+	if (get_magic_quotes_gpc()) {
656
+		return stripslashes($data);
657
+	}
658
+
659
+	$data = mysql_real_escape_string($data);
660
+
661
+	return $data;
662
+}
663
+
664
+//generic filter function for number cleaning data
665
+function filterFloat($data)
666
+{
667
+	$data = filter_var($data, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
668
+
669
+	if (get_magic_quotes_gpc()) {
670
+		return stripslashes($data);
671
+	}
672
+
673
+	$data = mysql_real_escape_string($data);
674
+
675
+	return $data;
676
+}
677
+
678
+?>
0 679
\ No newline at end of file