glongman-otv-ffiruby-filemagic 0.2.0 → 0.3.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/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