forked from OPSnet/Gazelle
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrecheck-file-storage.php
97 lines (85 loc) · 3.12 KB
/
recheck-file-storage.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<?php
/* Scan all the torrent storage directory and look for things that
* don't belong, and orphaned files of torrents that have been
* deleted (via moderation or catastrophe).
* Once it has been determined that all files reported do need to
* be removed, the output can be piped as follows:
*
* ... | awk '$1 != "##" {print $1}' | xargs rm
*
* and these extranenous files will be unlinked.
*
* In the commit this paragraph was added, the torrents_files
* table and the torrents_logs.Log column were removed. This file
* is left as-is, for historical purposes for people who want to
* migrate existing Gazelle installations.
*/
require_once(__DIR__ . '/../lib/bootstrap.php');
$allConfig = [
'-html' => [
'CHECK' => 'SELECT Log FROM torrents_logs WHERE TorrentID = ? AND LogID = ?',
'FILER' => new Gazelle\File\RipLogHTML(),
'MD5' => 'SELECT Log AS digest FROM torrents_logs WHERE TorrentID = ? AND LogID = ?',
'PIPE' => '/usr/bin/find ' . STORAGE_PATH_RIPLOGHTML . ' -type f',
'MATCH' => '~/(\d+)_(\d+)\.html$~',
'NEWLN' => true,
],
'-log' => [
'CHECK' => 'SELECT 1 FROM torrents_logs WHERE TorrentID = ? AND LogID = ?',
'FILER' => new Gazelle\File\RipLog(),
'MD5' => null,
'PIPE' => '/usr/bin/find ' . STORAGE_PATH_RIPLOG . ' -type f',
'MATCH' => '~/(\d+)_(\d+)\.log$~',
'NEWLN' => false,
],
'-torrent' => [
'CHECK' => 'SELECT 1 FROM torrents WHERE ID = ?',
'FILER' => new Gazelle\File\Torrent(),
'MD5' => 'SELECT File AS digest FROM torrents_files WHERE TorrentID = ?',
'PIPE' => '/usr/bin/find ' . STORAGE_PATH_TORRENT . ' -type f',
'MATCH' => '~/(\d+)\.torrent$~',
'NEWLN' => false,
],
];
if ($argc < 2 || !isset($allConfig[$argv[1]])) {
die('usage: ' . basename($argv[0]) . " <-html|-log|-torrent>\n");
}
$config = $allConfig[$argv[1]];
ini_set('max_execution_time', -1);
$find = popen($config['PIPE'], 'r');
if ($find === false) {
die("Could not popen(" . $config['PIPE'] . ")\n");
}
$db = Gazelle\DB::DB();
$begin = microtime(true);
$processed = 0;
$orphan = 0;
$alien = 0;
$mismatch = 0;
while (($file = fgets($find)) !== false) {
$file = trim($file);
++$processed;
if (!preg_match($config['MATCH'], $file, $match)) {
++$alien;
echo "$file is alien\n";
continue;
}
if (!$db->scalar($config['CHECK'], ...array_slice($match, 1))) {
++$orphan;
echo "$file is orphan\n";
continue;
}
if (is_null($config['MD5'])) {
continue;
}
$db_digest = md5($db->scalar($config['MD5'], ...array_slice($match, 1)) . ($config['NEWLN'] ? "\n" : ''));
$file_digest = md5((string)file_get_contents($file));
if ($db_digest != $file_digest) {
echo "$file contents $file_digest does not match db $db_digest\n";
++$mismatch;
}
}
$delta = microtime(true) - $begin;
printf("## Processed %d files in %0.1f seconds (%0.2f file/sec), %d orphan, %d alien, %d mismatch.\n",
$processed, $delta, $delta > 0 ? $processed / $delta : 0, $orphan, $alien, $mismatch
);