ruby-filemagic 0.6.2-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ChangeLog +92 -0
- data/README +101 -0
- data/Rakefile +34 -0
- data/TODO +7 -0
- data/ext/filemagic/extconf.rb +16 -0
- data/ext/filemagic/filemagic.c +310 -0
- data/ext/filemagic/filemagic.h +98 -0
- data/lib/filemagic/1.9/ruby_filemagic.so +0 -0
- data/lib/filemagic/2.0/ruby_filemagic.so +0 -0
- data/lib/filemagic/2.1/ruby_filemagic.so +0 -0
- data/lib/filemagic/2.2/ruby_filemagic.so +0 -0
- data/lib/filemagic/ext.rb +99 -0
- data/lib/filemagic/magic.mgc +0 -0
- data/lib/filemagic/version.rb +27 -0
- data/lib/filemagic.rb +142 -0
- data/lib/ruby-filemagic.rb +1 -0
- data/test/excel-example.xls +0 -0
- data/test/filemagic_test.rb +227 -0
- data/test/leaktest.rb +16 -0
- data/test/mahoro.c +187 -0
- data/test/perl +19 -0
- data/test/perl.mgc +0 -0
- data/test/pyfile +1 -0
- data/test/pyfile-compressed.gz +0 -0
- data/test/pylink +1 -0
- metadata +148 -0
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'filemagic'
|
2
|
+
|
3
|
+
module FileMagic::Ext
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.class_eval {
|
7
|
+
extend ClassMethods
|
8
|
+
include InstanceMethods
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
|
14
|
+
def file_type(file, *flags)
|
15
|
+
raise NotImplementedError, 'must be implemented by including class'
|
16
|
+
end
|
17
|
+
|
18
|
+
def file(file, *flags)
|
19
|
+
file_type(file, *flags)
|
20
|
+
end
|
21
|
+
|
22
|
+
def mime_type(file, *flags)
|
23
|
+
file_type(file, *flags.unshift(:mime))
|
24
|
+
end
|
25
|
+
|
26
|
+
alias_method :mime, :mime_type
|
27
|
+
|
28
|
+
def content_type(file, *flags)
|
29
|
+
mime_type(file, *flags << { simplified: true })
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
module InstanceMethods
|
35
|
+
|
36
|
+
def file_type(*flags)
|
37
|
+
self.class.file_type(self, *flags)
|
38
|
+
end
|
39
|
+
|
40
|
+
alias_method :file, :file_type
|
41
|
+
|
42
|
+
def mime_type(*flags)
|
43
|
+
self.class.mime_type(self, *flags)
|
44
|
+
end
|
45
|
+
|
46
|
+
alias_method :mime, :mime_type
|
47
|
+
|
48
|
+
def content_type(*flags)
|
49
|
+
self.class.content_type(self, *flags)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
class File
|
57
|
+
|
58
|
+
include FileMagic::Ext
|
59
|
+
|
60
|
+
def self.file_type(file, *flags)
|
61
|
+
FileMagic.fm(*flags).file(file.respond_to?(:path) ? file.path : file)
|
62
|
+
rescue FileMagic::FileMagicError
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
class String
|
68
|
+
|
69
|
+
include FileMagic::Ext
|
70
|
+
|
71
|
+
def self.file_type(string, *flags)
|
72
|
+
FileMagic.fm(*flags).buffer(string)
|
73
|
+
rescue FileMagic::FileMagicError
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
if $0 == __FILE__
|
79
|
+
f = __FILE__
|
80
|
+
p f
|
81
|
+
|
82
|
+
p File.file_type(f)
|
83
|
+
p File.mime_type(f)
|
84
|
+
p File.content_type(f)
|
85
|
+
|
86
|
+
f = File.new(f)
|
87
|
+
p f
|
88
|
+
|
89
|
+
p f.file_type
|
90
|
+
p f.mime_type
|
91
|
+
p f.content_type
|
92
|
+
|
93
|
+
s = '#! /usr/bin/ruby'
|
94
|
+
p s
|
95
|
+
|
96
|
+
p s.file_type
|
97
|
+
p s.mime_type
|
98
|
+
p s.content_type
|
99
|
+
end
|
Binary file
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class FileMagic
|
2
|
+
|
3
|
+
module Version
|
4
|
+
|
5
|
+
MAJOR = 0
|
6
|
+
MINOR = 6
|
7
|
+
TINY = 2
|
8
|
+
|
9
|
+
class << self
|
10
|
+
|
11
|
+
# Returns array representation.
|
12
|
+
def to_a
|
13
|
+
[MAJOR, MINOR, TINY]
|
14
|
+
end
|
15
|
+
|
16
|
+
# Short-cut for version string.
|
17
|
+
def to_s
|
18
|
+
to_a.join('.')
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
VERSION = Version.to_s
|
26
|
+
|
27
|
+
end
|
data/lib/filemagic.rb
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
begin
|
2
|
+
require "filemagic/#{RUBY_VERSION[/\d+.\d+/]}/ruby_filemagic"
|
3
|
+
rescue LoadError => err
|
4
|
+
raise if err.respond_to?(:path) && !err.path
|
5
|
+
require 'filemagic/ruby_filemagic'
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'filemagic/version'
|
9
|
+
|
10
|
+
class FileMagic
|
11
|
+
|
12
|
+
DEFAULT_MAGIC = __FILE__.sub(/\.rb\z/, '/magic.mgc')
|
13
|
+
|
14
|
+
ENV['MAGIC'] ||= DEFAULT_MAGIC unless path
|
15
|
+
|
16
|
+
# Map flag names to their values (:name => Integer).
|
17
|
+
FLAGS_BY_SYM = [
|
18
|
+
:none, # No flags
|
19
|
+
:debug, # Turn on debugging
|
20
|
+
:symlink, # Follow symlinks
|
21
|
+
:compress, # Check inside compressed files
|
22
|
+
:devices, # Look at the contents of devices
|
23
|
+
:mime_type, # Return only the MIME type
|
24
|
+
:continue, # Return all matches
|
25
|
+
:check, # Print warnings to stderr
|
26
|
+
:preserve_atime, # Restore access time on exit
|
27
|
+
:raw, # Don't translate unprint chars
|
28
|
+
:error, # Handle ENOENT etc as real errors
|
29
|
+
:mime_encoding, # Return only the MIME encoding
|
30
|
+
:mime, # MAGIC_MIME_TYPE | MAGIC_MIME_ENCODING
|
31
|
+
:apple, # Return the Apple creator and type
|
32
|
+
:no_check_compress, # Don't check for compressed files
|
33
|
+
:no_check_tar, # Don't check for tar files
|
34
|
+
:no_check_soft, # Don't check magic entries
|
35
|
+
:no_check_apptype, # Don't check application type
|
36
|
+
:no_check_elf, # Don't check for elf details
|
37
|
+
:no_check_text, # Don't check for text files
|
38
|
+
:no_check_cdf, # Don't check for cdf files
|
39
|
+
:no_check_tokens, # Don't check ascii/tokens
|
40
|
+
:no_check_encoding, # Don't check text encodings
|
41
|
+
:no_check_builtin, # No built-in tests; only consult the magic file
|
42
|
+
|
43
|
+
# Defined for backwards compatibility (renamed)
|
44
|
+
:no_check_ascii, # MAGIC_NO_CHECK_TEXT
|
45
|
+
|
46
|
+
# Defined for backwards compatibility; do nothing
|
47
|
+
:no_check_fortran, # Don't check ascii/fortran
|
48
|
+
:no_check_troff # Don't check ascii/troff
|
49
|
+
].inject({}) { |flags, flag|
|
50
|
+
const = "MAGIC_#{flag.to_s.upcase}"
|
51
|
+
flags.update(flag => const_defined?(const) && const_get(const))
|
52
|
+
}
|
53
|
+
|
54
|
+
# Map flag values to their names (Integer => :name).
|
55
|
+
FLAGS_BY_INT = FLAGS_BY_SYM.invert.update(0 => :none)
|
56
|
+
|
57
|
+
# Extract "simple" MIME type.
|
58
|
+
SIMPLE_RE = %r{([.\w\/-]+)}
|
59
|
+
|
60
|
+
@fm = {}
|
61
|
+
|
62
|
+
class << self
|
63
|
+
|
64
|
+
# Provide a "magic singleton".
|
65
|
+
def fm(*flags)
|
66
|
+
options = flags.last.is_a?(Hash) ? flags.pop : {}
|
67
|
+
|
68
|
+
if fm = @fm[key = [flags = flags(flags), options]]
|
69
|
+
return fm unless fm.closed?
|
70
|
+
end
|
71
|
+
|
72
|
+
@fm[key] = new(flags, options)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Clear our instance cache.
|
76
|
+
def clear!
|
77
|
+
@fm.each_value(&:close).clear
|
78
|
+
end
|
79
|
+
|
80
|
+
# Just like #new, but takes an optional block, in which case #close
|
81
|
+
# is called at the end and the value of the block is returned.
|
82
|
+
def open(*flags)
|
83
|
+
fm = new(*flags)
|
84
|
+
|
85
|
+
if block_given?
|
86
|
+
begin
|
87
|
+
yield fm
|
88
|
+
ensure
|
89
|
+
fm.close
|
90
|
+
end
|
91
|
+
else
|
92
|
+
fm
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Just a short-cut to #open with the +mime+ flag set.
|
97
|
+
def mime(*flags, &block)
|
98
|
+
open(:mime, *flags, &block)
|
99
|
+
end
|
100
|
+
|
101
|
+
def magic_version(default = MAGIC_VERSION)
|
102
|
+
default != '0' ? default :
|
103
|
+
user_magic_version ||
|
104
|
+
auto_magic_version ||
|
105
|
+
[default, 'unknown']
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def user_magic_version(key = 'MAGIC_VERSION')
|
111
|
+
[ENV[key], 'user-specified'] if ENV[key]
|
112
|
+
end
|
113
|
+
|
114
|
+
def auto_magic_version
|
115
|
+
require 'nuggets/file/which'
|
116
|
+
|
117
|
+
if cmd = File.which_command([
|
118
|
+
'dpkg-query -f \'${Version}\' -W libmagic-dev',
|
119
|
+
'file -v'
|
120
|
+
])
|
121
|
+
[%x{#{cmd}}[/\d+\.\d+/], 'auto-detected']
|
122
|
+
end
|
123
|
+
rescue LoadError
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
attr_writer :simplified
|
129
|
+
|
130
|
+
def simplified?
|
131
|
+
@simplified
|
132
|
+
end
|
133
|
+
|
134
|
+
def io(io, length = 8)
|
135
|
+
buffer(io.read(length))
|
136
|
+
end
|
137
|
+
|
138
|
+
def inspect
|
139
|
+
super.insert(-2, closed? ? ' (closed)' : '')
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'filemagic'
|
Binary file
|
@@ -0,0 +1,227 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'filemagic'
|
3
|
+
|
4
|
+
class TestFileMagic < Test::Unit::TestCase
|
5
|
+
|
6
|
+
magic_version, origin = FileMagic.magic_version
|
7
|
+
MAGIC_VERSION = magic_version.to_f
|
8
|
+
|
9
|
+
warn <<-EOT
|
10
|
+
|
11
|
+
libmagic version: #{MAGIC_VERSION}#{" (#{origin})" if origin}
|
12
|
+
magic file from #{FileMagic.path}
|
13
|
+
|
14
|
+
EOT
|
15
|
+
|
16
|
+
def test_file
|
17
|
+
fm = FileMagic.new(FileMagic::MAGIC_NONE)
|
18
|
+
|
19
|
+
python_script = match_version(
|
20
|
+
0 => 'a python script, ASCII text executable',
|
21
|
+
5.11 => 'Python script, ASCII text executable'
|
22
|
+
)
|
23
|
+
|
24
|
+
res = fm.file(path_to('pyfile'))
|
25
|
+
assert_equal(python_script, res)
|
26
|
+
|
27
|
+
if File.symlink?(path_to('pylink'))
|
28
|
+
res = fm.file(path_to('pylink'))
|
29
|
+
assert_equal("symbolic link to `pyfile'", res.strip)
|
30
|
+
end
|
31
|
+
|
32
|
+
fm.close
|
33
|
+
fm = FileMagic.new(FileMagic::MAGIC_SYMLINK)
|
34
|
+
|
35
|
+
res = fm.file(path_to('pylink'))
|
36
|
+
assert_equal(python_script, res)
|
37
|
+
|
38
|
+
fm.close
|
39
|
+
fm = FileMagic.new(FileMagic::MAGIC_SYMLINK | FileMagic::MAGIC_MIME)
|
40
|
+
|
41
|
+
res = fm.file(path_to('pylink'))
|
42
|
+
assert_equal('text/plain; charset=us-ascii', res)
|
43
|
+
|
44
|
+
fm.close
|
45
|
+
fm = FileMagic.new(FileMagic::MAGIC_COMPRESS)
|
46
|
+
|
47
|
+
res = fm.file(path_to('pyfile-compressed.gz'))
|
48
|
+
gzip_compressed = 'gzip compressed data, was "pyfile-compressed"'
|
49
|
+
assert_match(Gem.win_platform? ? /^#{gzip_compressed}/ :
|
50
|
+
/^#{python_script} \(#{gzip_compressed}/, res)
|
51
|
+
|
52
|
+
fm.close
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_buffer
|
56
|
+
fm = FileMagic.new(FileMagic::MAGIC_NONE)
|
57
|
+
res = fm.buffer("#!/bin/sh\n")
|
58
|
+
fm.close
|
59
|
+
assert_equal('POSIX shell script, ASCII text executable', res)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_check
|
63
|
+
return if Gem.win_platform?
|
64
|
+
fm = FileMagic.new(FileMagic::MAGIC_NONE)
|
65
|
+
res = silence_stderr { fm.check(path_to('perl')) }
|
66
|
+
fm.close
|
67
|
+
assert(res)
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_check_compiled
|
71
|
+
return if MAGIC_VERSION <= 5.09
|
72
|
+
fm = FileMagic.new(FileMagic::MAGIC_NONE)
|
73
|
+
res = silence_stderr { fm.check(path_to('perl.mgc')) }
|
74
|
+
fm.close
|
75
|
+
assert(res)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_compile
|
79
|
+
assert(File.writable?('.'), "can't write to current directory")
|
80
|
+
fm = FileMagic.new(FileMagic::MAGIC_NONE)
|
81
|
+
res = fm.compile(path_to('perl'))
|
82
|
+
fm.close
|
83
|
+
assert(res)
|
84
|
+
File.unlink(path_to('perl.mgc', '.'))
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_block
|
88
|
+
block_fm = nil
|
89
|
+
res = FileMagic.open(FileMagic::MAGIC_NONE) { |fm|
|
90
|
+
block_fm = fm
|
91
|
+
fm.file(path_to('pyfile'))
|
92
|
+
}
|
93
|
+
assert_equal(match_version(
|
94
|
+
0 => 'a python script, ASCII text executable',
|
95
|
+
5.11 => 'Python script, ASCII text executable'
|
96
|
+
), res)
|
97
|
+
assert block_fm.closed?
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_flags_to_int
|
101
|
+
assert_raise(TypeError) { FileMagic.flags(0) }
|
102
|
+
assert_equal(0, FileMagic.flags([FileMagic::MAGIC_NONE]))
|
103
|
+
assert_equal(0, FileMagic.flags([:none]))
|
104
|
+
assert_equal(0, FileMagic.flags([]))
|
105
|
+
assert_equal(1072, FileMagic.flags([:mime, :continue]))
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_setflags
|
109
|
+
fm = FileMagic.new(FileMagic::MAGIC_NONE)
|
110
|
+
assert_equal([], fm.flags)
|
111
|
+
fm.flags = FileMagic::MAGIC_SYMLINK
|
112
|
+
assert_equal([:symlink], fm.flags)
|
113
|
+
fm.close
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_abbr
|
117
|
+
fm = FileMagic.new(:mime, :continue)
|
118
|
+
assert_equal([:mime_type, :continue, :mime_encoding], fm.flags)
|
119
|
+
fm.flags = :symlink
|
120
|
+
assert_equal([:symlink], fm.flags)
|
121
|
+
fm.close
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_close
|
125
|
+
fm = FileMagic.new
|
126
|
+
fm.close
|
127
|
+
assert fm.closed?
|
128
|
+
fm.close
|
129
|
+
assert fm.closed?
|
130
|
+
end
|
131
|
+
|
132
|
+
# tests adapted from mahoro:
|
133
|
+
|
134
|
+
def test_mahoro_file
|
135
|
+
fm = FileMagic.new
|
136
|
+
fm.flags = FileMagic::MAGIC_NONE
|
137
|
+
assert_equal(match_version(
|
138
|
+
0 => 'ASCII C program text',
|
139
|
+
5.11 => 'C source, ASCII text'
|
140
|
+
), fm.file(path_to('mahoro.c')))
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_mahoro_mime_file
|
144
|
+
fm = FileMagic.new
|
145
|
+
fm.flags = FileMagic::MAGIC_MIME
|
146
|
+
assert_equal('text/x-c; charset=us-ascii', fm.file(path_to('mahoro.c')))
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_mahoro_buffer
|
150
|
+
fm = FileMagic.new
|
151
|
+
fm.flags = FileMagic::MAGIC_NONE
|
152
|
+
assert_equal(match_version(
|
153
|
+
0 => 'ASCII C program text',
|
154
|
+
5.11 => 'C source, ASCII text'
|
155
|
+
), fm.buffer(File.read(path_to('mahoro.c'))))
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_mahoro_mime_buffer
|
159
|
+
fm = FileMagic.new
|
160
|
+
fm.flags = FileMagic::MAGIC_MIME
|
161
|
+
assert_equal('text/x-c; charset=us-ascii', fm.buffer(File.read(path_to('mahoro.c'))))
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_mahoro_valid
|
165
|
+
fm = FileMagic.new
|
166
|
+
assert(silence_stderr { fm.valid? }, 'Default database was not valid.')
|
167
|
+
end
|
168
|
+
|
169
|
+
# test abbreviating mime types
|
170
|
+
|
171
|
+
def test_abbrev_mime_type
|
172
|
+
fm = FileMagic.mime
|
173
|
+
|
174
|
+
refute fm.simplified?
|
175
|
+
assert_equal('text/plain; charset=us-ascii', fm.file(path_to('perl')))
|
176
|
+
|
177
|
+
fm.simplified = true
|
178
|
+
assert fm.simplified?
|
179
|
+
assert_equal('text/plain', fm.file(path_to('perl')))
|
180
|
+
assert_equal(match_version(
|
181
|
+
0 => 'application/vnd.ms-office',
|
182
|
+
5.11 => 'application/msword',
|
183
|
+
5.14 => 'application/vnd.ms-office'
|
184
|
+
), fm.file(path_to('excel-example.xls')))
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_singleton
|
188
|
+
fm1 = FileMagic.fm
|
189
|
+
assert_equal(fm1, FileMagic.fm)
|
190
|
+
|
191
|
+
refute fm1.simplified?
|
192
|
+
assert_equal('ASCII text', fm1.file(path_to('perl')))
|
193
|
+
|
194
|
+
fm2 = FileMagic.fm(:mime)
|
195
|
+
assert_equal(fm2, FileMagic.fm(:mime))
|
196
|
+
refute_equal(fm2, fm1)
|
197
|
+
|
198
|
+
refute fm2.simplified?
|
199
|
+
assert_equal('text/plain; charset=us-ascii', fm2.file(path_to('perl')))
|
200
|
+
|
201
|
+
fm3 = FileMagic.fm(:mime, simplified: true)
|
202
|
+
assert_equal(fm3, FileMagic.fm(:mime, simplified: true))
|
203
|
+
refute_equal(fm3, fm2)
|
204
|
+
refute_equal(fm3, fm1)
|
205
|
+
|
206
|
+
assert fm3.simplified?
|
207
|
+
assert_equal('text/plain', fm3.file(path_to('perl')))
|
208
|
+
end
|
209
|
+
|
210
|
+
# utility methods:
|
211
|
+
|
212
|
+
def path_to(file, dir = File.dirname(__FILE__))
|
213
|
+
File.join(dir, file)
|
214
|
+
end
|
215
|
+
|
216
|
+
def silence_stderr
|
217
|
+
require 'nuggets/io/redirect'
|
218
|
+
$stderr.redirect { yield }
|
219
|
+
rescue LoadError
|
220
|
+
yield
|
221
|
+
end
|
222
|
+
|
223
|
+
def match_version(versions)
|
224
|
+
versions.sort_by { |k,| -k }.find { |k,| k <= MAGIC_VERSION }.last
|
225
|
+
end
|
226
|
+
|
227
|
+
end
|
data/test/leaktest.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
require 'filemagic'
|
3
|
+
|
4
|
+
warn "watch -n 1 'ps aux | grep [l]eaktest'"
|
5
|
+
|
6
|
+
def do_file(filename)
|
7
|
+
fm = FileMagic.new(0)
|
8
|
+
file = fm.file(filename)
|
9
|
+
fm.close
|
10
|
+
return file
|
11
|
+
end
|
12
|
+
|
13
|
+
loop do
|
14
|
+
puts do_file($0)
|
15
|
+
sleep 1
|
16
|
+
end
|
data/test/mahoro.c
ADDED
@@ -0,0 +1,187 @@
|
|
1
|
+
/*
|
2
|
+
* This file is Public Domain.
|
3
|
+
*/
|
4
|
+
|
5
|
+
#include <ruby.h>
|
6
|
+
#include <magic.h>
|
7
|
+
|
8
|
+
struct MagicCookie
|
9
|
+
{
|
10
|
+
magic_t cookie;
|
11
|
+
};
|
12
|
+
|
13
|
+
static VALUE cMahoro;
|
14
|
+
static VALUE eMahoroError;
|
15
|
+
|
16
|
+
static void
|
17
|
+
mahoro_free(ptr)
|
18
|
+
struct MagicCookie *ptr;
|
19
|
+
{
|
20
|
+
magic_close(ptr->cookie);
|
21
|
+
free(ptr);
|
22
|
+
}
|
23
|
+
|
24
|
+
static VALUE
|
25
|
+
mahoro_allocate(klass)
|
26
|
+
VALUE klass;
|
27
|
+
{
|
28
|
+
return Data_Wrap_Struct(klass, 0, mahoro_free, 0);
|
29
|
+
}
|
30
|
+
|
31
|
+
static VALUE
|
32
|
+
mahoro_initialize(argc, argv, self)
|
33
|
+
int argc;
|
34
|
+
VALUE *argv, self;
|
35
|
+
{
|
36
|
+
int flags = MAGIC_NONE;
|
37
|
+
char *path = 0;
|
38
|
+
struct MagicCookie *ptr;
|
39
|
+
magic_t cookie;
|
40
|
+
VALUE vpath, vflags;
|
41
|
+
|
42
|
+
switch(rb_scan_args(argc, argv, "02", &vflags, &vpath)) {
|
43
|
+
case 2:
|
44
|
+
if(!NIL_P(vpath)) {
|
45
|
+
path = StringValuePtr(vpath);
|
46
|
+
}
|
47
|
+
/* fallthrough */
|
48
|
+
case 1:
|
49
|
+
flags = FIX2INT(vflags);
|
50
|
+
break;
|
51
|
+
}
|
52
|
+
|
53
|
+
if(!(cookie = magic_open(flags))) {
|
54
|
+
rb_raise(eMahoroError, "failed to initialize magic cookie");
|
55
|
+
}
|
56
|
+
|
57
|
+
if(magic_load(cookie, path)) {
|
58
|
+
rb_raise(eMahoroError, "failed to load database: %s",
|
59
|
+
magic_error(cookie));
|
60
|
+
}
|
61
|
+
|
62
|
+
ptr = ALLOC(struct MagicCookie);
|
63
|
+
ptr->cookie = cookie;
|
64
|
+
DATA_PTR(self) = ptr;
|
65
|
+
|
66
|
+
return self;
|
67
|
+
}
|
68
|
+
|
69
|
+
static VALUE
|
70
|
+
mahoro_file(self, path)
|
71
|
+
VALUE self, path;
|
72
|
+
{
|
73
|
+
const char *msg;
|
74
|
+
magic_t cookie = ((struct MagicCookie *) DATA_PTR(self))->cookie;
|
75
|
+
|
76
|
+
if(!(msg = magic_file(cookie, StringValuePtr(path)))) {
|
77
|
+
rb_raise(eMahoroError, "failed lookup: %s", magic_error(cookie));
|
78
|
+
}
|
79
|
+
|
80
|
+
return rb_str_new2(msg);
|
81
|
+
}
|
82
|
+
|
83
|
+
static VALUE
|
84
|
+
mahoro_buffer(self, input)
|
85
|
+
VALUE self, input;
|
86
|
+
{
|
87
|
+
const char *msg;
|
88
|
+
magic_t cookie = ((struct MagicCookie *) DATA_PTR(self))->cookie;
|
89
|
+
|
90
|
+
if(!(msg = magic_buffer(cookie, StringValuePtr(input),
|
91
|
+
RSTRING(StringValue(input))->len))) {
|
92
|
+
rb_raise(eMahoroError, "failed lookup: %s", magic_error(cookie));
|
93
|
+
}
|
94
|
+
|
95
|
+
return rb_str_new2(msg);
|
96
|
+
}
|
97
|
+
|
98
|
+
static VALUE
|
99
|
+
mahoro_set_flags(self, flags)
|
100
|
+
VALUE self, flags;
|
101
|
+
{
|
102
|
+
magic_t cookie = ((struct MagicCookie *) DATA_PTR(self))->cookie;
|
103
|
+
|
104
|
+
return INT2FIX(magic_setflags(cookie, FIX2INT(flags)));
|
105
|
+
}
|
106
|
+
|
107
|
+
static VALUE
|
108
|
+
mahoro_check(argc, argv, self)
|
109
|
+
int argc;
|
110
|
+
VALUE *argv, self;
|
111
|
+
{
|
112
|
+
char *path = 0;
|
113
|
+
VALUE vpath;
|
114
|
+
magic_t cookie = ((struct MagicCookie *) DATA_PTR(self))->cookie;
|
115
|
+
|
116
|
+
switch(rb_scan_args(argc, argv, "01", &vpath)) {
|
117
|
+
case 1:
|
118
|
+
if(!NIL_P(vpath)) {
|
119
|
+
path = StringValuePtr(vpath);
|
120
|
+
}
|
121
|
+
break;
|
122
|
+
}
|
123
|
+
|
124
|
+
if(!magic_check(cookie, path)) {
|
125
|
+
return Qtrue;
|
126
|
+
} else {
|
127
|
+
return Qfalse;
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
131
|
+
static VALUE
|
132
|
+
mahoro_compile(klass, path)
|
133
|
+
VALUE klass, path;
|
134
|
+
{
|
135
|
+
magic_t cookie = magic_open(MAGIC_NONE);
|
136
|
+
|
137
|
+
if(magic_compile(cookie, StringValuePtr(path))) {
|
138
|
+
rb_raise(eMahoroError, "failed compile: %s", magic_error(cookie));
|
139
|
+
}
|
140
|
+
|
141
|
+
magic_close(cookie);
|
142
|
+
|
143
|
+
return Qtrue;
|
144
|
+
}
|
145
|
+
|
146
|
+
static VALUE
|
147
|
+
mahoro_load(self, path)
|
148
|
+
VALUE self, path;
|
149
|
+
{
|
150
|
+
magic_t cookie = ((struct MagicCookie *) DATA_PTR(self))->cookie;
|
151
|
+
|
152
|
+
if(magic_load(cookie, StringValuePtr(path))) {
|
153
|
+
rb_raise(eMahoroError, "failed load: %s", magic_error(cookie));
|
154
|
+
}
|
155
|
+
|
156
|
+
return self;
|
157
|
+
}
|
158
|
+
|
159
|
+
void Init_mahoro(void)
|
160
|
+
{
|
161
|
+
cMahoro = rb_define_class("Mahoro", rb_cObject);
|
162
|
+
eMahoroError = rb_define_class_under(cMahoro, "Error", rb_eStandardError);
|
163
|
+
|
164
|
+
rb_const_set(cMahoro, rb_intern("NONE"), INT2FIX(MAGIC_NONE));
|
165
|
+
rb_const_set(cMahoro, rb_intern("DEBUG"), INT2FIX(MAGIC_DEBUG));
|
166
|
+
rb_const_set(cMahoro, rb_intern("SYMLINK"), INT2FIX(MAGIC_SYMLINK));
|
167
|
+
rb_const_set(cMahoro, rb_intern("COMPRESS"), INT2FIX(MAGIC_COMPRESS));
|
168
|
+
rb_const_set(cMahoro, rb_intern("DEVICES"), INT2FIX(MAGIC_DEVICES));
|
169
|
+
rb_const_set(cMahoro, rb_intern("MIME"), INT2FIX(MAGIC_MIME));
|
170
|
+
rb_const_set(cMahoro, rb_intern("CONTINUE"), INT2FIX(MAGIC_CONTINUE));
|
171
|
+
rb_const_set(cMahoro, rb_intern("CHECK"), INT2FIX(MAGIC_CHECK));
|
172
|
+
rb_const_set(cMahoro, rb_intern("PRESERVE_ATIME"),
|
173
|
+
INT2FIX(MAGIC_PRESERVE_ATIME));
|
174
|
+
rb_const_set(cMahoro, rb_intern("RAW"), INT2FIX(MAGIC_RAW));
|
175
|
+
rb_const_set(cMahoro, rb_intern("ERROR"), INT2FIX(MAGIC_ERROR));
|
176
|
+
|
177
|
+
rb_define_alloc_func(cMahoro, mahoro_allocate);
|
178
|
+
rb_define_method(cMahoro, "initialize", mahoro_initialize, -1);
|
179
|
+
rb_define_method(cMahoro, "file", mahoro_file, 1);
|
180
|
+
rb_define_method(cMahoro, "buffer", mahoro_buffer, 1);
|
181
|
+
rb_define_method(cMahoro, "flags=", mahoro_set_flags, 1);
|
182
|
+
rb_define_method(cMahoro, "valid?", mahoro_check, -1);
|
183
|
+
rb_define_singleton_method(cMahoro, "compile", mahoro_compile, 1);
|
184
|
+
rb_define_method(cMahoro, "load", mahoro_load, 1);
|
185
|
+
}
|
186
|
+
|
187
|
+
/* arch-tag: mahoro */
|