glongman-otv-ffiruby-filemagic 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION.yml +4 -0
- data/lib/ffi_file_magic.rb +116 -0
- data/test/ffiruby_filemagic_test.rb +66 -0
- data/test/leaktest.rb +15 -0
- data/test/perl +19 -0
- data/test/pyfile +1 -0
- data/test/pyfile-compressed.gz +0 -0
- data/test/test_helper.rb +7 -0
- metadata +69 -0
data/VERSION.yml
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'ffi'
|
3
|
+
class FFIFileMagicError < StandardError; end
|
4
|
+
class FFIFileMagic
|
5
|
+
# constants (see magic.h)
|
6
|
+
MAGIC_NONE =0x000000 # No flags
|
7
|
+
MAGIC_DEBUG =0x000001 # Turn on debugging
|
8
|
+
MAGIC_SYMLINK =0x000002 # Follow symlinks
|
9
|
+
MAGIC_COMPRESS =0x000004 # Check inside compressed files
|
10
|
+
MAGIC_DEVICES =0x000008 # Look at the contents of devices
|
11
|
+
MAGIC_MIME_TYPE =0x000010 # Return only the MIME type
|
12
|
+
MAGIC_CONTINUE =0x000020 # Return all matches
|
13
|
+
MAGIC_CHECK =0x000040 # Print warnings to stderr
|
14
|
+
MAGIC_PRESERVE_ATIME =0x000080 # Restore access time on exit
|
15
|
+
MAGIC_RAW =0x000100 # Don't translate unprint chars
|
16
|
+
MAGIC_ERROR =0x000200 # Handle ENOENT etc as real errors
|
17
|
+
MAGIC_MIME_ENCODING =0x000400 # Return only the MIME encoding
|
18
|
+
MAGIC_MIME =(FFIFileMagic::MAGIC_MIME_TYPE|FFIFileMagic::MAGIC_MIME_ENCODING)
|
19
|
+
MAGIC_NO_CHECK_COMPRESS =0x001000 # Don't check for compressed files
|
20
|
+
MAGIC_NO_CHECK_TAR =0x002000 # Don't check for tar files
|
21
|
+
MAGIC_NO_CHECK_SOFT =0x004000 # Don't check magic entries
|
22
|
+
MAGIC_NO_CHECK_APPTYPE =0x008000 # Don't check application type
|
23
|
+
MAGIC_NO_CHECK_ELF =0x010000 # Don't check for elf details
|
24
|
+
MAGIC_NO_CHECK_ASCII =0x020000 # Don't check for ascii files
|
25
|
+
MAGIC_NO_CHECK_TOKENS =0x100000 # Don't check ascii/tokens
|
26
|
+
|
27
|
+
def initialize(flags)
|
28
|
+
@cookie = Native::magic_open(flags)
|
29
|
+
raise "out of memory" unless @cookie
|
30
|
+
raise FFIFileMagicError, Native::magic_error(@cookie) if Native::magic_load(@cookie, nil) == -1
|
31
|
+
end
|
32
|
+
|
33
|
+
def check_cookie
|
34
|
+
raise "invalid state: closed" unless @cookie
|
35
|
+
end
|
36
|
+
|
37
|
+
# returns a textual description of the contents of the filename argument
|
38
|
+
def file(filename)
|
39
|
+
check_cookie
|
40
|
+
raise FFIFileMagicError, Native::magic_error(@cookie) if (result = Native::magic_file(@cookie, filename)) == nil
|
41
|
+
result
|
42
|
+
end
|
43
|
+
|
44
|
+
# returns a textual description of the contents of the string argument
|
45
|
+
def buffer(string)
|
46
|
+
check_cookie
|
47
|
+
raise FFIFileMagicError, Native::magic_error(@cookie) if (result = Native::magic_buffer(@cookie, string, string.length)) == nil
|
48
|
+
result
|
49
|
+
end
|
50
|
+
|
51
|
+
# checks the validity of entries in the colon separated database files passed in as filename
|
52
|
+
def check(filename)
|
53
|
+
check_cookie
|
54
|
+
Native::magic_check(@cookie, filename);
|
55
|
+
end
|
56
|
+
# compile the the colon separated list of database files passed in as filename
|
57
|
+
def compile(filename)
|
58
|
+
check_cookie
|
59
|
+
Native::magic_compile(@cookie, filename);
|
60
|
+
end
|
61
|
+
|
62
|
+
# closes the magic database and frees any memory allocated.
|
63
|
+
# if memory is a concern, use this.
|
64
|
+
def close
|
65
|
+
check_cookie
|
66
|
+
Native::magic_close(@cookie);
|
67
|
+
@cookie = nil
|
68
|
+
end
|
69
|
+
|
70
|
+
module Native
|
71
|
+
extend FFI::Library
|
72
|
+
|
73
|
+
begin
|
74
|
+
ffi_lib 'magic'
|
75
|
+
rescue LoadError
|
76
|
+
libsuffix = %x(uname -a) =~ /Darwin/ ? '.dylib' : '.so'
|
77
|
+
ffi_lib "/opt/local/lib/libmagic" + libsuffix
|
78
|
+
end
|
79
|
+
|
80
|
+
#magic_t is a pointer (I think)
|
81
|
+
#magic_t magic_open(int);
|
82
|
+
attach_function :magic_open, [:int], :pointer
|
83
|
+
|
84
|
+
#void magic_close(magic_t);
|
85
|
+
attach_function :magic_close, [:pointer], :void
|
86
|
+
|
87
|
+
# const char *magic_file(magic_t, const char *);
|
88
|
+
attach_function :magic_file, [:pointer, :string], :string
|
89
|
+
|
90
|
+
# const char *magic_descriptor(magic_t, int);
|
91
|
+
attach_function :magic_descriptor, [:pointer, :int], :string
|
92
|
+
|
93
|
+
# const char *magic_buffer(magic_t, const void *, size_t);
|
94
|
+
attach_function :magic_buffer, [:pointer, :pointer, :int], :string
|
95
|
+
|
96
|
+
# const char *magic_error(magic_t);
|
97
|
+
attach_function :magic_error, [:pointer], :string
|
98
|
+
|
99
|
+
# int magic_setflags(magic_t, int);
|
100
|
+
attach_function :magic_setflags, [:pointer, :int], :int
|
101
|
+
|
102
|
+
# int magic_load(magic_t, const char *);
|
103
|
+
attach_function :magic_load, [:pointer, :string], :int
|
104
|
+
|
105
|
+
# int magic_compile(magic_t, const char *);
|
106
|
+
attach_function :magic_compile, [:pointer, :string], :int
|
107
|
+
|
108
|
+
# int magic_check(magic_t, const char *);
|
109
|
+
attach_function :magic_check, [:pointer, :string], :int
|
110
|
+
|
111
|
+
# int magic_errno(magic_t);
|
112
|
+
attach_function :magic_errno, [:pointer], :int
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
require 'ruby-debug'
|
3
|
+
class TestFFIFileMagic < Test::Unit::TestCase
|
4
|
+
BASE = File.expand_path(File.dirname(__FILE__)) + "/"
|
5
|
+
FILE = BASE + "pyfile"
|
6
|
+
LINK = BASE + 'pylink'
|
7
|
+
COMPRESSED = BASE + 'pyfile-compressed.gz'
|
8
|
+
PERL = BASE + "perl"
|
9
|
+
DB = File.expand_path(BASE + '../perl.mgc')
|
10
|
+
def test_file
|
11
|
+
fm = FFIFileMagic.new(FFIFileMagic::MAGIC_NONE)
|
12
|
+
res = fm.file FILE
|
13
|
+
assert_equal("a python script text executable", res)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_symlink
|
17
|
+
File.symlink FILE, LINK
|
18
|
+
fm = FFIFileMagic.new(FFIFileMagic::MAGIC_NONE)
|
19
|
+
res = fm.file LINK
|
20
|
+
assert_match(/^symbolic link to `.*pyfile'$/, res)
|
21
|
+
fm.close
|
22
|
+
fm = FFIFileMagic.new(FFIFileMagic::MAGIC_SYMLINK)
|
23
|
+
res = fm.file LINK
|
24
|
+
assert_equal("a python script text executable", res)
|
25
|
+
fm.close
|
26
|
+
fm = FFIFileMagic.new(FFIFileMagic::MAGIC_SYMLINK | FFIFileMagic::MAGIC_MIME)
|
27
|
+
res = fm.file LINK
|
28
|
+
assert_equal("text/plain charset=us-ascii", res)
|
29
|
+
fm.close
|
30
|
+
ensure
|
31
|
+
File.unlink LINK
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_compressed
|
35
|
+
fm = FFIFileMagic.new(FFIFileMagic::MAGIC_COMPRESS)
|
36
|
+
res = fm.file COMPRESSED
|
37
|
+
assert_match(/^a python script text executable/, res)
|
38
|
+
fm.close
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_buffer
|
42
|
+
fm = FFIFileMagic.new(FFIFileMagic::MAGIC_NONE)
|
43
|
+
res = fm.buffer("#!/bin/sh\n")
|
44
|
+
fm.close
|
45
|
+
assert_equal("POSIX shell script text executable", res)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_check
|
49
|
+
fm = FFIFileMagic.new(FFIFileMagic::MAGIC_NONE)
|
50
|
+
res = fm.check PERL
|
51
|
+
fm.close
|
52
|
+
assert_equal(0, res)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_compile
|
56
|
+
fm = FFIFileMagic.new(FFIFileMagic::MAGIC_NONE)
|
57
|
+
res = fm.compile PERL
|
58
|
+
fm.close
|
59
|
+
assert_equal(0, res)
|
60
|
+
File.unlink DB
|
61
|
+
end
|
62
|
+
|
63
|
+
def file(name)
|
64
|
+
File.expand_path(File.dirname(__FILE__)) + "/" + name
|
65
|
+
end
|
66
|
+
end
|
data/test/leaktest.rb
ADDED
data/test/perl
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
#------------------------------------------------------------------------------
|
3
|
+
# perl: file(1) magic for Larry Wall's perl language.
|
4
|
+
#
|
5
|
+
# The ``eval'' line recognizes an outrageously clever hack for USG systems.
|
6
|
+
# Keith Waclena <keith@cerberus.uchicago.edu>
|
7
|
+
# Send additions to <perl5-porters@perl.org>
|
8
|
+
0 string/b #!\ /bin/perl perl script text executable
|
9
|
+
0 string eval\ "exec\ /bin/perl perl script text
|
10
|
+
0 string/b #!\ /usr/bin/perl perl script text executable
|
11
|
+
0 string eval\ "exec\ /usr/bin/perl perl script text
|
12
|
+
0 string/b #!\ /usr/local/bin/perl perl script text
|
13
|
+
0 string eval\ "exec\ /usr/local/bin/perl perl script text executable
|
14
|
+
0 string eval\ '(exit\ $?0)'\ &&\ eval\ 'exec perl script text
|
15
|
+
|
16
|
+
# a couple more, by me
|
17
|
+
# XXX: christos matches
|
18
|
+
#0 regex package Perl5 module source text (via regex)
|
19
|
+
0 string package Perl5 module source text
|
data/test/pyfile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
"""
|
Binary file
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: glongman-otv-ffiruby-filemagic
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Geoff Longman
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-02-02 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: ffi
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: "0"
|
23
|
+
version:
|
24
|
+
description: new implementation of the ancient ruby-filemagic gem. Uses FFI to talk to native library
|
25
|
+
email: glongman@overlay.tv
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files: []
|
31
|
+
|
32
|
+
files:
|
33
|
+
- VERSION.yml
|
34
|
+
- lib/ffi_file_magic.rb
|
35
|
+
- test/ffiruby_filemagic_test.rb
|
36
|
+
- test/leaktest.rb
|
37
|
+
- test/perl
|
38
|
+
- test/pyfile
|
39
|
+
- test/pyfile-compressed.gz
|
40
|
+
- test/test_helper.rb
|
41
|
+
has_rdoc: true
|
42
|
+
homepage: http://github.com/glongman-otv/ffiruby-filemagic
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options:
|
45
|
+
- --inline-source
|
46
|
+
- --charset=UTF-8
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
version:
|
61
|
+
requirements: []
|
62
|
+
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 1.2.0
|
65
|
+
signing_key:
|
66
|
+
specification_version: 2
|
67
|
+
summary: new implementation of the ancient ruby-filemagic gem. Uses FFI to talk to native library
|
68
|
+
test_files: []
|
69
|
+
|