Subversion Repositories checksum-tools

Rev

Rev 14 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 14 Rev 15
Line 1... Line 1...
1
#!/usr/bin/php
1
#!/usr/bin/php
2
<?php
2
<?php
3
 
3
 
4
/*
4
/*
5
   Copyright 2020 Daniel Marschall, ViaThinkSoft
5
   Copyright 2020-2022 Daniel Marschall, ViaThinkSoft
6
 
6
 
7
   Licensed under the Apache License, Version 2.0 (the "License");
7
   Licensed under the Apache License, Version 2.0 (the "License");
8
   you may not use this file except in compliance with 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
9
   You may obtain a copy of the License at
10
 
10
 
Line 15... Line 15...
15
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
   See the License for the specific language governing permissions and
16
   See the License for the specific language governing permissions and
17
   limitations under the License.
17
   limitations under the License.
18
*/
18
*/
19
 
19
 
20
// TODO: make use of STDERR and return different exit codes
-
 
21
// TODO: On Windows file systems, accept file names case insensitively
20
// TODO: On Windows file systems, accept file names case insensitively
22
 
21
 
23
function utf8_normalize($str) {
22
function utf8_normalize($str) {
24
        // This helps to handle decomposite Unicode endpoints (E.g. German Umlauts have different representations)
23
        // This helps to handle decomposite Unicode endpoints (E.g. German Umlauts have different representations)
25
        // Requires php-intl
24
        // Requires php-intl
Line 37... Line 36...
37
}
36
}
38
 
37
 
39
function testmd5($file) {
38
function testmd5($file) {
40
        // TODO: warn if an entry is multiple times (with different checksums) in a single file
39
        // TODO: warn if an entry is multiple times (with different checksums) in a single file
41
        if (!file_exists($file)) {
40
        if (!file_exists($file)) {
42
                echo "ERROR: File $file does not exist.\n";
41
                fwrite(STDERR, "ERROR: File $file does not exist.\n");
43
                return;
42
                return;
44
        }
43
        }
45
 
44
 
46
        $files_checked = array();
45
        $files_checked = array();
47
 
46
 
Line 65... Line 64...
65
                $line = str_replace("\t", ' ', $line);
64
                $line = str_replace("\t", ' ', $line);
66
                list($checksum, $origname) = explode(' ', $line, 2);
65
                list($checksum, $origname) = explode(' ', $line, 2);
67
                $origname = dirname($file) . '/' . trim($origname);
66
                $origname = dirname($file) . '/' . trim($origname);
68
                $checksum = trim($checksum);
67
                $checksum = trim($checksum);
69
                if (!file_exists($origname)) {
68
                if (!file_exists($origname)) {
70
                        echo "WARNING: File vanished : $origname\n";
69
                        fwrite(STDERR, "WARNING: File vanished : $origname\n");
71
                } else {
70
                } else {
72
                        if (is_file($origname)) {
71
                        if (is_file($origname)) {
73
                                $checksum2 = md5_file($origname);
72
                                $checksum2 = md5_file($origname);
74
                                if (strtolower($checksum) != strtolower($checksum2)) {
73
                                if (strtolower($checksum) != strtolower($checksum2)) {
75
                                        echo "CHECKSUM FAIL: $origname (expected $checksum, but is $checksum2)\n";
74
                                        fwrite(STDERR, "CHECKSUM FAIL: $origname (expected $checksum, but is $checksum2)\n");
76
                                } else {
75
                                } else {
77
                                        global $show_verbose;
76
                                        global $show_verbose;
78
                                        if ($show_verbose) echo "OK: $origname\n";
77
                                        if ($show_verbose) echo "OK: $origname\n";
79
                                }
78
                                }
80
                        } else {
79
                        } else {
81
                                // For some reason, some files on a NTFS volume are "FIFO" pipe files?!
80
                                // For some reason, some files on a NTFS volume are "FIFO" pipe files?!
82
                                echo "Warning: $origname is not a regular file!\n";
81
                                fwrite(STDERR, "Warning: $origname is not a regular file!\n");
83
                        }
82
                        }
84
                }
83
                }
85
 
84
 
86
                $origname = utf8_normalize(basename($origname));
85
                $origname = utf8_normalize(basename($origname));
87
                $files_checked[] = dirname($file) . '/' . $origname;
86
                $files_checked[] = dirname($file) . '/' . $origname;
Line 89... Line 88...
89
 
88
 
90
        // Now check if files have vanished!
89
        // Now check if files have vanished!
91
        $directory = dirname($file);
90
        $directory = dirname($file);
92
        $sd = @scandir($directory);
91
        $sd = @scandir($directory);
93
        if ($sd === false) {
92
        if ($sd === false) {
94
                echo "Error: Cannot scan directory $directory\n";
93
                fwrite(STDERR, "Error: Cannot scan directory $directory\n");
95
        } else {
94
        } else {
96
                foreach ($sd as $file) {
95
                foreach ($sd as $file) {
97
                        if ($file === '.') continue;
96
                        if ($file === '.') continue;
98
                        if ($file === '..') continue;
97
                        if ($file === '..') continue;
-
 
98
                        if (substr($file,0,1) === '.') continue;
99
                        if (strtolower($file) === 'thumbs.db') continue;
99
                        if (strtolower($file) === 'thumbs.db') continue;
100
                        if (strtolower(substr($file, -4)) === '.md5') continue;
100
                        if (strtolower(substr($file, -4)) === '.md5') continue;
101
                        if (strtolower(substr($file, -4)) === '.sfv') continue;
101
                        if (strtolower(substr($file, -4)) === '.sfv') continue;
102
                        $fullpath = $directory . '/' . $file;
102
                        $fullpath = $directory . '/' . $file;
103
                        if (!is_dir($fullpath)) {
103
                        if (!is_dir($fullpath)) {
104
                                $fullpath = utf8_normalize($fullpath);
104
                                $fullpath = utf8_normalize($fullpath);
105
                                if (!in_array($fullpath,$files_checked)) {
105
                                if (!in_array($fullpath,$files_checked)) {
106
                                        echo "Warning: File not in SFV checksum file: $fullpath\n";
106
                                        fwrite(STDERR, "Warning: File not in SFV checksum file: $fullpath\n");
107
                                }
107
                                }
108
                        }
108
                        }
109
                }
109
                }
110
        }
110
        }
111
}
111
}
112
 
112
 
113
function _rec($directory) {
113
function _rec($directory) {
114
        $directory = rtrim($directory, '/\\');
114
        $directory = rtrim($directory, '/\\');
115
 
115
 
116
        if (!is_dir($directory)) {
116
        if (!is_dir($directory)) {
117
                exit("Invalid directory path $directory\n");
117
                fwrite(STDERR, "Invalid directory path $directory\n");
-
 
118
                return false;
118
        }
119
        }
119
 
120
 
120
        if ($dont_add_files = count(glob("$directory/*.md5")) == 0) {
121
        if ($dont_add_files = count(glob("$directory/*.md5")) == 0) {
121
                global $show_verbose;
122
                global $show_verbose;
122
                if ($show_verbose) echo "Directory $directory has no MD5 file. Skipping.\n";
123
                if ($show_verbose) echo "Directory $directory has no MD5 file. Skipping.\n";
Line 131... Line 132...
131
                }
132
                }
132
        }
133
        }
133
 
134
 
134
        $sd = @scandir($directory);
135
        $sd = @scandir($directory);
135
        if ($sd === false) {
136
        if ($sd === false) {
136
                echo "Error: Cannot scan directory $directory\n";
137
                fwrite(STDERR, "Error: Cannot scan directory $directory\n");
137
                return;
138
                return false;
138
        }
139
        }
139
 
140
 
140
        foreach ($sd as $file) {
141
        foreach ($sd as $file) {
141
                if ($file !== '.' && $file !== '..') {
142
                if ($file !== '.' && $file !== '..') {
142
                        $file = $directory . '/' . $file;
143
                        $file = $directory . '/' . $file;
143
                        if (is_dir($file)) {
144
                        if (is_dir($file)) {
144
                                _rec($file);
145
                                _rec($file);
145
                        }
146
                        }
146
                }
147
                }
147
        }
148
        }
-
 
149
 
-
 
150
        return true;
148
}
151
}
149
 
152
 
150
 
153
 
151
# ---
154
# ---
152
 
155
 
153
$show_verbose = false;
156
$show_verbose = false;
154
$dir = '';
157
$dirs = array();
155
 
158
 
156
for ($i=1; $i<$argc; $i++) {
159
for ($i=1; $i<$argc; $i++) {
157
        if ($argv[$i] == '-v') {
160
        if ($argv[$i] == '-v') {
158
                $show_verbose = true;
161
                $show_verbose = true;
159
        } else {
162
        } else {
160
                $dir = $argv[$i];
163
                $dirs[] = $argv[$i];
161
        }
164
        }
162
}
165
}
163
 
166
 
164
if (empty($dir)) {
167
if (count($dirs) == 0) {
165
        echo "Syntax: $argv[0] [-v] <directory>\n";
168
        echo "Syntax: $argv[0] [-v] <directory> [<directory> [...]]\n";
166
        exit(2);
169
        exit(2);
167
}
170
}
168
 
171
 
-
 
172
$res = 0;
169
if (!is_dir($dir)) {
173
foreach ($dirs as $dir) {
170
        echo "Directory not found\n";
174
        if (!_rec($dir)) $res = 1;
171
        exit(1);
-
 
172
}
175
}
173
 
-
 
174
_rec($dir);
-
 
175
 
-
 
176
if ($show_verbose) echo "Done.\n";
176
if ($show_verbose) echo "Done.\n";
-
 
177
exit($res);
-
 
178