glongman-otv-ffiruby-filemagic 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|