fingerprint 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright (c) 2010 Samuel Williams. Released under the GNU GPLv3.
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ require 'optparse'
18
+ require 'fingerprint'
19
+
20
+ OPTIONS = {
21
+ :root => "./",
22
+ :mode => :scan,
23
+ :output => nil
24
+ }
25
+
26
+ ARGV.options do |o|
27
+ script_name = File.basename($0)
28
+
29
+ o.banner = "Usage: #{script_name} [options]"
30
+ o.define_head "This script is used to calculate and compare a basic file system fingerprint."
31
+
32
+ o.on("-c", "Compare the given fingerprints. Check that the second fingerprint is a superset of the first.") do
33
+ OPTIONS[:mode] = :check
34
+ end
35
+
36
+ o.on("-o [output-path]", String, "Write the fingerprint output to the given file.") do |path|
37
+ OPTIONS[:output] = File.open(path, "w")
38
+ end
39
+
40
+ o.separator ""
41
+ o.separator "Help and Copyright information"
42
+
43
+ o.on_tail("--copy", "Display copyright information") {
44
+ puts "#{script_name} v#{Fingerprint::VERSION::STRING}. Copyright (c) 2010 Samuel Williams. Released under the GPLv3."
45
+ puts "See http://www.oriontransfer.co.nz/ for more information."
46
+
47
+ exit
48
+ }
49
+
50
+ o.on_tail("-h", "--help", "Show this help message.") { puts o; exit }
51
+ end.parse!
52
+
53
+ case (OPTIONS[:mode])
54
+ when :scan
55
+ Fingerprint::Scanner.scan_dirs(ARGV, OPTIONS[:output] || $stdout)
56
+ when :check
57
+ error_count = Fingerprint::Checker.check_files(ARGV[0], ARGV[1])
58
+ exit(error_count > 0 ? 1 : 0)
59
+ end
@@ -0,0 +1,19 @@
1
+ # Copyright (c) 2010 Samuel Williams. Released under the GNU GPLv3.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require 'fingerprint/version'
17
+ require 'fingerprint/scanner'
18
+ require 'fingerprint/checker'
19
+
@@ -0,0 +1,82 @@
1
+ # Copyright (c) 2010 Samuel Williams. Released under the GNU GPLv3.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require 'set'
17
+
18
+ module Fingerprint
19
+ # Check that every file specified in fp2 exists in fp1 correctly,
20
+ # i.e. ensure that the fingerprint fp2 accurately is a superset of
21
+ # fp1
22
+ class Checker
23
+ def initialize(fp1, fp2)
24
+ @fp1 = fp1
25
+ @fp2 = fp2
26
+ @mismatches = []
27
+ end
28
+
29
+ def check (&block)
30
+ @fp1.seek(0)
31
+ @fp2.seek(0)
32
+
33
+ @dst = Set.new
34
+ @dst_paths = {}
35
+ @dst_hashes = {}
36
+
37
+ # Parse original fingerprint
38
+ @fp2.each_line do |line|
39
+ if line.chomp.match(/^([a-fA-F0-9]{32}): (.*)$/)
40
+ @dst.add([$1, $2])
41
+
42
+ @dst_paths[$2] = $1
43
+ @dst_hashes[$1] ||= Set.new
44
+ @dst_hashes[$1].add($2)
45
+ end
46
+ end
47
+
48
+ # For every file in the src, we check that it exists
49
+ # in the destination:
50
+ @fp1.each_line do |line|
51
+ if line.chomp.match(/^([a-fA-F0-9]{32}): (.*)$/)
52
+ yield($1, $2, self) unless dst.include?([$1, $2])
53
+ end
54
+ end
55
+ end
56
+
57
+ attr :dst
58
+ attr :dst_paths
59
+ attr :dst_hashes
60
+
61
+ def self.check_files(p1, p2)
62
+ puts "Comparing src: #{p1.dump} with dst: #{p2.dump}..."
63
+ error_count = 0
64
+ checker = Checker.new(File.open(p1), File.open(p2))
65
+
66
+ checker.check do |hash, path|
67
+ error_count += 1
68
+
69
+ if !checker.dst_paths[path]
70
+ puts "Source file: #{path.dump} does not exist in destination!"
71
+ elsif checker.dst_paths[path] != hash
72
+ puts "Destination file: #{path.dump} is different!"
73
+ else
74
+ puts "Unknown error for path: #{path.dump}"
75
+ end
76
+ end
77
+
78
+ return error_count
79
+ end
80
+
81
+ end
82
+ end
@@ -0,0 +1,86 @@
1
+ # Copyright (c) 2010 Samuel Williams. Released under the GNU GPLv3.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require 'stringio'
17
+ require 'find'
18
+ require 'digest'
19
+
20
+ module Fingerprint
21
+
22
+ class Scanner
23
+ def initialize(dirs)
24
+ @dirs = dirs
25
+ @dirs << Dir.pwd if dirs.size == 0
26
+
27
+ @excludes = [/^\._/]
28
+
29
+ @output = StringIO.new
30
+ end
31
+
32
+ def output_dir(path)
33
+ @output.puts ""
34
+ @output.puts((" " * 32) + " #{path}")
35
+ end
36
+
37
+ def output_file(path)
38
+ d = Digest::MD5.new
39
+
40
+ File.open(path) do |f|
41
+ while buf = f.read(1024*1024*10)
42
+ d << buf
43
+ end
44
+ end
45
+
46
+ @output.puts "#{d.hexdigest}: #{path}"
47
+ end
48
+
49
+ def excluded?(path)
50
+ @excludes.each do |exclusion|
51
+ if exclusion.match(path)
52
+ return true
53
+ end
54
+ end
55
+
56
+ return false
57
+ end
58
+
59
+ def process
60
+ for dir in @dirs
61
+ Dir.chdir(dir) do
62
+ Find.find("./") do |path|
63
+ if FileTest.directory?(path)
64
+ if excluded?(path)
65
+ Find.prune # Ignore this directory
66
+ else
67
+ output_dir(path)
68
+ end
69
+ else
70
+ output_file(path) unless excluded?(path)
71
+ end
72
+ end
73
+ end # Dir.chdir
74
+ end
75
+ end
76
+
77
+ attr :output, true
78
+
79
+ def self.scan_dirs(dirs, output = $stdout)
80
+ scanner = Scanner.new(dirs)
81
+ scanner.output = output
82
+
83
+ scanner.process
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,24 @@
1
+ # Copyright (c) 2010 Samuel Williams. Released under the GNU GPLv3.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ module Fingerprint
17
+ module VERSION #:nodoc:
18
+ MAJOR = 1
19
+ MINOR = 0
20
+ TINY = 0
21
+
22
+ STRING = [MAJOR, MINOR, TINY].join('.')
23
+ end
24
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fingerprint
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Samuel Williams
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-10-20 00:00:00 +13:00
19
+ default_executable: fingerprint
20
+ dependencies: []
21
+
22
+ description:
23
+ email: samuel@oriontransfer.org
24
+ executables:
25
+ - fingerprint
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - bin/fingerprint
32
+ - lib/fingerprint/checker.rb
33
+ - lib/fingerprint/scanner.rb
34
+ - lib/fingerprint/version.rb
35
+ - lib/fingerprint.rb
36
+ has_rdoc: true
37
+ homepage: http://www.oriontransfer.co.nz/software/admin-toolbox/fingerprint
38
+ licenses: []
39
+
40
+ post_install_message:
41
+ rdoc_options: []
42
+
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ hash: 3
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ requirements: []
64
+
65
+ rubyforge_project:
66
+ rubygems_version: 1.3.7
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: Fingerprint is a tool for creating checksums of entire directory structures, and comparing them for inconsistencies.
70
+ test_files: []
71
+