Subversion Repositories checksum-tools

Rev

Rev 2 | Rev 5 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 daniel-mar 1
#!/usr/bin/php
2
<?php
3
 
4
/*
5
   Copyright 2020 Daniel Marschall, ViaThinkSoft
6
 
7
   Licensed under the Apache License, Version 2.0 (the "License");
8
   you may not use this file except in compliance with the License.
9
   You may obtain a copy of the License at
10
 
11
       http://www.apache.org/licenses/LICENSE-2.0
12
 
13
   Unless required by applicable law or agreed to in writing, software
14
   distributed under the License is distributed on an "AS IS" BASIS,
15
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
   See the License for the specific language governing permissions and
17
   limitations under the License.
18
*/
19
 
4 daniel-mar 20
// TODO: make use of STDERR and return different exit codes
21
 
2 daniel-mar 22
function testsfv($file) {
23
        // TODO: warn if an entry is multiple times (with different checksums) in a single file
24
        if (!file_exists($file)) {
25
                echo "ERROR: File $file does not exist.\n";
26
                return;
27
        }
28
 
29
        $lines = file($file);
4 daniel-mar 30
        $is_first_line = true;
31
        $force_utf8 = false;
2 daniel-mar 32
        foreach ($lines as $line) {
4 daniel-mar 33
                if ($is_first_line) {
34
                        $tmp = 0;
35
                        $line = str_replace("\xEF\xBB\xBF",'',$line,$tmp);
36
                        if ($tmp > 0) $force_utf8 = true;
37
                        $is_first_line = false;
38
                }
39
                $is_ansi = strstr(utf8_decode($line),'?') !== false; // Attention: This assumes that '?' is not part of the line!
40
                if (!$force_utf8 && $is_ansi) $line = utf8_encode($line);
41
 
2 daniel-mar 42
                $line = rtrim($line);
43
                if ($line == '') continue;
44
                $checksum = substr($line,-8);
45
                $origname = rtrim(substr($line,0,strlen($line)-8));
46
                $origname = dirname($file) . '/' . trim($origname);
47
                if (!file_exists($origname)) {
48
                        echo "WARNING: File vanished : $origname\n";
49
                } else {
50
                        $checksum2 = crc32_file($origname);
51
                        if (strtolower($checksum) != strtolower($checksum2)) {
52
                                echo "CHECKSUM FAIL: $origname (expected $checksum, but is $checksum2)\n";
53
                        } else {
4 daniel-mar 54
                                global $show_verbose;
55
                                if ($show_verbose) echo "OK: $origname\n";
2 daniel-mar 56
                        }
57
                }
58
                // TODO: Also warn about extra files which are not indexed
59
        }
60
}
61
 
62
function swapEndianness($hex) {
63
        return implode('', array_reverse(str_split($hex, 2)));
64
}
65
 
66
function crc32_file($filename, $rawOutput = false) {
67
        $out = bin2hex(hash_file ('crc32b', $filename , true));
68
        if (hash('crc32b', 'TEST') == 'b893eaee') {
69
                // hash_file() in PHP 5.2 has the wrong Endianess!
70
                // https://bugs.php.net/bug.php?id=47467
71
                $out = swapEndianness($out);
72
        }
73
        return $out;
74
}
75
 
76
function _rec($directory) {
4 daniel-mar 77
        $directory = rtrim($directory, '/\\');
78
 
2 daniel-mar 79
        if (!is_dir($directory)) {
80
                exit("Invalid directory path $directory\n");
81
        }
82
 
83
        if ($dont_add_files = count(glob("$directory/*.sfv")) == 0) {
4 daniel-mar 84
                global $show_verbose;
85
                if ($show_verbose) echo "Directory $directory has no SFV file. Skipping.\n";
2 daniel-mar 86
        } else {
87
                $out = array();
88
 
4 daniel-mar 89
                global $show_verbose;
90
                if ($show_verbose) echo "Check directory $directory\n";
91
                $sfvfiles = glob($directory.'/*.sfv');
2 daniel-mar 92
                foreach ($sfvfiles as $sfvfile) {
93
                        testsfv($sfvfile);
94
                }
95
        }
96
 
4 daniel-mar 97
        $sd = @scandir($directory);
98
        if ($sd === false) {
99
                echo "Error: Cannot scan directory $directory\n";
100
                return;
101
        }
102
 
103
        foreach ($sd as $file) {
2 daniel-mar 104
                if ($file !== '.' && $file !== '..') {
105
                        $file = $directory . '/' . $file;
106
                        if (is_dir($file)) {
107
                                _rec($file);
108
                        }
109
                }
110
        }
111
}
112
 
113
 
114
# ---
115
 
4 daniel-mar 116
$show_verbose = false;
117
$dir = '';
118
 
119
for ($i=1; $i<$argc; $i++) {
120
        if ($argv[$i] == '-v') {
121
                $show_verbose = true;
122
        } else {
123
                $dir = $argv[$i];
124
        }
125
}
126
 
127
if (empty($dir)) {
128
        echo "Syntax: $argv[0] [-v] <directory>\n";
2 daniel-mar 129
        exit(2);
130
}
131
 
4 daniel-mar 132
if (!is_dir($dir)) {
2 daniel-mar 133
        echo "Directory not found\n";
134
        exit(1);
135
}
136
 
4 daniel-mar 137
_rec($dir);
2 daniel-mar 138
 
4 daniel-mar 139
if ($show_verbose) echo "Done.\n";