glongman-otv-ffiruby-filemagic 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -1,6 +1,8 @@
1
1
  ffiruby-filemagic
2
2
  =================
3
3
 
4
+ Win32 Support? sorry.
5
+
4
6
  A new implementation of the ancient ruby-filemagic gem (http://grub.ath.cx/filemagic/).
5
7
 
6
8
  This version uses FFI to talk to the native library (JRuby friendly).
@@ -15,27 +17,45 @@ What is FileMagic?
15
17
 
16
18
  Install:
17
19
 
18
- Make sure you have the magic(4) library installed. On OSX this can be done using MacPorts (http://www.macports.org/)
20
+ Make sure you have the magic(4) library installed.
19
21
 
20
- > sudo port install file
21
22
  > sudo gem sources -a http://gems.github.com
22
23
  > sudo gem install glongman-otv-ffiruby-filemagic
23
24
 
24
- - Linux? should just work
25
- - Cygwin? no idea, never use it
26
- - Windows? see above
27
-
28
- Usage:
25
+ After Install:
29
26
 
30
27
  > irb
31
28
  >> require 'ffi_file_magic'
32
29
  => true
33
30
  >> fm = FFIFileMagic.new(FFIFileMagic::MAGIC_MIME)
34
31
  => #<FFIFileMagic:0x11a4d9c @cookie=#<Native Pointer address=0x13606f0>>
35
- >> fm.file('rails.png')
32
+ >> fm.file('rails.png') #supply a path to your own image
36
33
  => "image/png"
37
34
  >>
38
35
 
36
+ Install Problems?
37
+
38
+ If the gem complains that it can't find the magic library you can run the setup.rb file
39
+ in the root of the gem
40
+
41
+ > sudo ruby /path/to/ffiruby-filemagic/setup.rb (where is the gem? 'gem contents ffiruby-filemagic')
42
+
43
+ Without any arguments setup.rb will look around the filesystem for a magic library and test to see if
44
+ that library is compatible. If so a small modification will be made so the gem will work.
45
+
46
+ You can run setup.rb more than once.
47
+
48
+ you can also tell setup.rb exactly where to look for the magic libary
49
+
50
+ > sudo ruby /path/to/ffiruby-filemagic/setup.rb --with-magic-lib=/opt/local/lib
51
+
52
+ This gem has been tested with the magic library shipped with File 4.26 from ftp://ftp.astron.com/pub/file
53
+
54
+ On OSX, and at the time of writing this, you can get file using macports (http://www.macports.org/)
55
+
56
+ > sudo port install file
57
+
58
+ On other Unix variants, download the source, build and install. then run setup.rb
39
59
 
40
60
  COPYRIGHT
41
61
  =========
data/Rakefile CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'rake'
2
2
  require 'rake/testtask'
3
3
  require 'rake/rdoctask'
4
+ require 'ruby-debug'
4
5
 
5
6
  begin
6
7
  require 'jeweler'
@@ -12,7 +13,7 @@ begin
12
13
  s.description = %Q{new implementation of the ancient ruby-filemagic gem. Uses FFI to talk to native library}
13
14
  s.authors = ["Geoff Longman"]
14
15
  s.add_dependency 'ffi'
15
- s.files = FileList["[A-Z]*", "{lib,test}/**/*"]
16
+ s.files = FileList["setup.rb", "[A-Z]*", "{lib,test}/**/*"]
16
17
  end
17
18
  rescue LoadError
18
19
  puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :patch: 0
3
3
  :major: 0
4
- :minor: 2
4
+ :minor: 3
@@ -1,116 +1 @@
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
-
1
+ require File.dirname(__FILE__) + '/ffi_file_magic/ffi_file_magic.rb'
@@ -0,0 +1,111 @@
1
+ require 'rubygems'
2
+ require 'ffi'
3
+ require File.expand_path(File.dirname(__FILE__) + '/load_library.rb')
4
+ class FFIFileMagicError < StandardError; end
5
+ class FFIFileMagic
6
+ INSTALL_PATH = nil #installation found libmagic here
7
+ # constants (see magic.h)
8
+ MAGIC_NONE =0x000000 # No flags
9
+ MAGIC_DEBUG =0x000001 # Turn on debugging
10
+ MAGIC_SYMLINK =0x000002 # Follow symlinks
11
+ MAGIC_COMPRESS =0x000004 # Check inside compressed files
12
+ MAGIC_DEVICES =0x000008 # Look at the contents of devices
13
+ MAGIC_MIME_TYPE =0x000010 # Return only the MIME type
14
+ MAGIC_CONTINUE =0x000020 # Return all matches
15
+ MAGIC_CHECK =0x000040 # Print warnings to stderr
16
+ MAGIC_PRESERVE_ATIME =0x000080 # Restore access time on exit
17
+ MAGIC_RAW =0x000100 # Don't translate unprint chars
18
+ MAGIC_ERROR =0x000200 # Handle ENOENT etc as real errors
19
+ MAGIC_MIME_ENCODING =0x000400 # Return only the MIME encoding
20
+ MAGIC_MIME =(FFIFileMagic::MAGIC_MIME_TYPE|FFIFileMagic::MAGIC_MIME_ENCODING)
21
+ MAGIC_NO_CHECK_COMPRESS =0x001000 # Don't check for compressed files
22
+ MAGIC_NO_CHECK_TAR =0x002000 # Don't check for tar files
23
+ MAGIC_NO_CHECK_SOFT =0x004000 # Don't check magic entries
24
+ MAGIC_NO_CHECK_APPTYPE =0x008000 # Don't check application type
25
+ MAGIC_NO_CHECK_ELF =0x010000 # Don't check for elf details
26
+ MAGIC_NO_CHECK_ASCII =0x020000 # Don't check for ascii files
27
+ MAGIC_NO_CHECK_TOKENS =0x100000 # Don't check ascii/tokens
28
+
29
+ def initialize(flags)
30
+ @cookie = Native::magic_open(flags)
31
+ raise "out of memory" unless @cookie
32
+ raise FFIFileMagicError, Native::magic_error(@cookie) if Native::magic_load(@cookie, nil) == -1
33
+ end
34
+
35
+ def check_cookie
36
+ raise "invalid state: closed" unless @cookie
37
+ end
38
+
39
+ # returns a textual description of the contents of the filename argument
40
+ def file(filename)
41
+ check_cookie
42
+ raise FFIFileMagicError, Native::magic_error(@cookie) if (result = Native::magic_file(@cookie, filename)) == nil
43
+ result
44
+ end
45
+
46
+ # returns a textual description of the contents of the string argument
47
+ def buffer(string)
48
+ check_cookie
49
+ raise FFIFileMagicError, Native::magic_error(@cookie) if (result = Native::magic_buffer(@cookie, string, string.length)) == nil
50
+ result
51
+ end
52
+
53
+ # checks the validity of entries in the colon separated database files passed in as filename
54
+ def check(filename)
55
+ check_cookie
56
+ Native::magic_check(@cookie, filename);
57
+ end
58
+ # compile the the colon separated list of database files passed in as filename
59
+ def compile(filename)
60
+ check_cookie
61
+ Native::magic_compile(@cookie, filename);
62
+ end
63
+
64
+ # closes the magic database and frees any memory allocated.
65
+ # if memory is a concern, use this.
66
+ def close
67
+ check_cookie
68
+ Native::magic_close(@cookie);
69
+ @cookie = nil
70
+ end
71
+
72
+ module Native
73
+ extend FFI::Library
74
+ include FFIFileMagic::Native::LoadLibrary
75
+
76
+ #magic_t is a pointer (I think)
77
+ #magic_t magic_open(int);
78
+ attach_function :magic_open, [:int], :pointer
79
+
80
+ #void magic_close(magic_t);
81
+ attach_function :magic_close, [:pointer], :void
82
+
83
+ # const char *magic_file(magic_t, const char *);
84
+ attach_function :magic_file, [:pointer, :string], :string
85
+
86
+ # const char *magic_descriptor(magic_t, int);
87
+ attach_function :magic_descriptor, [:pointer, :int], :string
88
+
89
+ # const char *magic_buffer(magic_t, const void *, size_t);
90
+ attach_function :magic_buffer, [:pointer, :pointer, :int], :string
91
+
92
+ # const char *magic_error(magic_t);
93
+ attach_function :magic_error, [:pointer], :string
94
+
95
+ # int magic_setflags(magic_t, int);
96
+ attach_function :magic_setflags, [:pointer, :int], :int
97
+
98
+ # int magic_load(magic_t, const char *);
99
+ attach_function :magic_load, [:pointer, :string], :int
100
+
101
+ # int magic_compile(magic_t, const char *);
102
+ attach_function :magic_compile, [:pointer, :string], :int
103
+
104
+ # int magic_check(magic_t, const char *);
105
+ attach_function :magic_check, [:pointer, :string], :int
106
+
107
+ # int magic_errno(magic_t);
108
+ attach_function :magic_errno, [:pointer], :int
109
+
110
+ end
111
+ end
@@ -0,0 +1,12 @@
1
+ class FFIFileMagic
2
+ module Native
3
+ module LoadLibrary
4
+ def self.included(base)
5
+ base.class_eval do
6
+ # setup.rb found this library as suitable
7
+ ffi_lib '/opt/local/lib/libmagic.dylib'
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
data/setup.rb ADDED
@@ -0,0 +1,131 @@
1
+ require 'optparse'
2
+ require "rubygems"
3
+ require "ffi"
4
+
5
+
6
+ libname = FFI.map_library_name('magic')
7
+
8
+ module FFIFileMagic
9
+ module Checker
10
+ def self.check_lib(path)
11
+ begin
12
+ dylib = FFI::DynamicLibrary.open(path, FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_LOCAL)
13
+ rescue LoadError
14
+ return
15
+ end
16
+ puts "checking for needed methods in #{dylib.name}"
17
+ result = true
18
+ [:magic_open, :magic_close, :magic_file,
19
+ :magic_buffer, :magic_error, :magic_setflags,
20
+ :magic_load, :magic_compile, :magic_check,
21
+ :magic_errno].each do |method|
22
+ result &= begin
23
+ print "\tmethod exists? #{method} ... "
24
+ if dylib.find_symbol(method.to_s)
25
+ puts "yes"; true
26
+ else
27
+ puts "no"; false
28
+ end
29
+ end
30
+ end
31
+ if result
32
+ puts "\t#{dylib.name} suitable? ... #{result ? 'yes' : 'no'}"; return dylib
33
+ end
34
+ end
35
+ end
36
+ end
37
+ #sorry, no windows
38
+ if RUBY_PLATFORM =~ /mswin/
39
+ raise <<END_MSWIN
40
+ \nInstall Failed
41
+ +--------------------------------------------------------------------+
42
+ | This gem is for use only on Linux, BSD, OS X, and similar systems. |
43
+ +--------------------------------------------------------------------+
44
+ END_MSWIN
45
+ end
46
+
47
+ op = nil
48
+ ARGV.options do |op|
49
+ op.def_option('--with-magic-lib=ARBITRARY', '-l', 'arg') do |arg|
50
+ puts arg
51
+ $user_lib_path = File.join(arg, libname) if arg
52
+ end
53
+ end
54
+ ARGV.options.parse!
55
+
56
+ dylib = nil
57
+ if $user_lib_path
58
+ #user supplied
59
+ dylib = FFIFileMagic::Checker.check_lib($user_lib_path)
60
+ puts "No suitable magic library found at #{$user_lib_path}" unless dylib
61
+ end
62
+
63
+
64
+ unless dylib || $user_lib_path
65
+ # no fuss, no muss?
66
+ dylib = default_dylib = FFIFileMagic::Checker.check_lib('magic')
67
+ end
68
+
69
+ unless dylib || $user_lib_path
70
+ #check some usual suspects
71
+ paths = %w{ /lib/ /usr/lib/ /usr/local/lib/ /opt/local/lib/}
72
+ found_path = nil
73
+ paths.uniq.each do |path|
74
+ full_path = path + libname
75
+ if File.exist? full_path
76
+ begin
77
+ break if (dylib = FFIFileMagic::Checker.check_lib(full_path))
78
+ rescue LoadError; end
79
+ end
80
+ end
81
+ end
82
+
83
+ unless dylib
84
+ raise <<END_FAIL
85
+ \nInstall Failed
86
+ +----------------------------------------------------------------------------+
87
+ | Could not find a suitable magic library. |
88
+ | |
89
+ | OSX - use macports http://www.macports.org/ |
90
+ | > port install file |
91
+ | |
92
+ | Others - build file from source - ftp://ftp.astron.com/pub/file/ |
93
+ +----------------------------------------------------------------------------+
94
+ END_FAIL
95
+ end
96
+
97
+ template =<<END_TEMPLATE
98
+ class FFIFileMagic
99
+ module Native
100
+ module LoadLibrary
101
+ def self.included(base)
102
+ base.class_eval do
103
+ # setup.rb found this library as suitable
104
+ ffi_lib '#{dylib.name}'
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
110
+ END_TEMPLATE
111
+
112
+ if dylib
113
+ print "writing path #{dylib.name} into lib/ffi_file_magic/load_library.rb ...."
114
+ load_library = File.expand_path(File.dirname(__FILE__) + '/lib/ffi_file_magic/load_library.rb')
115
+ File.open(load_library, 'w') do |file|
116
+ file.write template
117
+ end
118
+ puts "success"
119
+ end
120
+
121
+ puts "\n Finished."
122
+
123
+
124
+
125
+
126
+
127
+
128
+
129
+
130
+
131
+
@@ -1,12 +1,12 @@
1
1
  require File.dirname(__FILE__) + '/test_helper'
2
- require 'ruby-debug'
2
+
3
3
  class TestFFIFileMagic < Test::Unit::TestCase
4
4
  BASE = File.expand_path(File.dirname(__FILE__)) + "/"
5
5
  FILE = BASE + "pyfile"
6
6
  LINK = BASE + 'pylink'
7
7
  COMPRESSED = BASE + 'pyfile-compressed.gz'
8
8
  PERL = BASE + "perl"
9
- DB = File.expand_path(BASE + '../perl.mgc')
9
+ DB = File.expand_path(BASE + '/perl.mgc')
10
10
  def test_file
11
11
  fm = FFIFileMagic.new(FFIFileMagic::MAGIC_NONE)
12
12
  res = fm.file FILE
@@ -51,13 +51,15 @@ class TestFFIFileMagic < Test::Unit::TestCase
51
51
  fm.close
52
52
  assert_equal(0, res)
53
53
  end
54
-
54
+
55
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
56
+ Dir.chdir(File.dirname(__FILE__)) do
57
+ fm = FFIFileMagic.new(FFIFileMagic::MAGIC_NONE)
58
+ res = fm.compile PERL
59
+ fm.close
60
+ assert_equal(0, res)
61
+ File.unlink DB
62
+ end
61
63
  end
62
64
 
63
65
  def file(name)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glongman-otv-ffiruby-filemagic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Geoff Longman
@@ -9,11 +9,12 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-02-03 00:00:00 -08:00
12
+ date: 2009-02-21 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: ffi
17
+ type: :runtime
17
18
  version_requirement:
18
19
  version_requirements: !ruby/object:Gem::Requirement
19
20
  requirements:
@@ -30,10 +31,14 @@ extensions: []
30
31
  extra_rdoc_files: []
31
32
 
32
33
  files:
34
+ - setup.rb
33
35
  - LICENSE
34
36
  - Rakefile
35
37
  - README
36
38
  - VERSION.yml
39
+ - lib/ffi_file_magic
40
+ - lib/ffi_file_magic/ffi_file_magic.rb
41
+ - lib/ffi_file_magic/load_library.rb
37
42
  - lib/ffi_file_magic.rb
38
43
  - test/ffiruby_filemagic_test.rb
39
44
  - test/leaktest.rb