glongman-ffiruby-filemagic 0.3.3

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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Overlay TV
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,63 @@
1
+ ffiruby-filemagic
2
+ =================
3
+
4
+ Win32 Support? sorry.
5
+
6
+ A new implementation of the ancient ruby-filemagic gem (http://grub.ath.cx/filemagic/).
7
+
8
+ This version uses FFI to talk to the native library (JRuby friendly).
9
+
10
+ (Blurb from the original gem site follows)
11
+
12
+ What is FileMagic?
13
+
14
+ FileMagic is a Ruby binding to the magic(4) library, which you may know better as the file(1) command.
15
+ The file command identifies the type of a file using, among other tests, a test for whether the file
16
+ begins with a certain magic number.
17
+
18
+ Install:
19
+
20
+ Make sure you have the magic(4) library installed.
21
+
22
+ > sudo gem sources -a http://gems.github.com
23
+ > sudo gem install glongman-ffiruby-filemagic
24
+
25
+ After Install:
26
+
27
+ > irb
28
+ >> require 'ffi_file_magic'
29
+ => true
30
+ >> fm = FFIFileMagic.new(FFIFileMagic::MAGIC_MIME)
31
+ => #<FFIFileMagic:0x11a4d9c @cookie=#<Native Pointer address=0x13606f0>>
32
+ >> fm.file('rails.png') #supply a path to your own image
33
+ => "image/png"
34
+ >>
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
59
+
60
+ COPYRIGHT
61
+ =========
62
+
63
+ Copyright (c) 2009 Overlay TV. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+ require 'ruby-debug'
5
+
6
+ begin
7
+ require 'jeweler'
8
+ Jeweler::Tasks.new do |s|
9
+ s.name = "ffiruby-filemagic"
10
+ s.summary = %Q{new implementation of the ancient ruby-filemagic gem. Uses FFI to talk to native library}
11
+ s.email = "glongman@overlay.tv"
12
+ s.homepage = "http://github.com/glongman/ffiruby-filemagic"
13
+ s.description = %Q{new implementation of the ancient ruby-filemagic gem. Uses FFI to talk to native library}
14
+ s.authors = ["Geoff Longman"]
15
+ s.add_dependency 'ffi'
16
+ s.files = FileList["setup.rb", "[A-Z]*", "{lib,test}/**/*"]
17
+ end
18
+ rescue LoadError
19
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
20
+ end
21
+
22
+ Rake::TestTask.new do |t|
23
+ t.libs << 'lib'
24
+ t.pattern = 'test/**/*_test.rb'
25
+ t.verbose = false
26
+ end
27
+
28
+ Rake::RDocTask.new do |rdoc|
29
+ rdoc.rdoc_dir = 'rdoc'
30
+ rdoc.title = 'ffiruby-filemagic'
31
+ rdoc.options << '--line-numbers' << '--inline-source'
32
+ rdoc.rdoc_files.include('README*')
33
+ rdoc.rdoc_files.include('lib/**/*.rb')
34
+ end
35
+
36
+ begin
37
+ require 'rcov/rcovtask'
38
+ Rcov::RcovTask.new do |t|
39
+ t.libs << 'test'
40
+ t.test_files = FileList['test/**/*_test.rb']
41
+ t.verbose = true
42
+ end
43
+ rescue LoadError
44
+ end
45
+
46
+ task :default => :test
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :patch: 3
3
+ :major: 0
4
+ :minor: 3
@@ -0,0 +1 @@
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
+
@@ -0,0 +1,68 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
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
+ 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
63
+ end
64
+
65
+ def file(name)
66
+ File.expand_path(File.dirname(__FILE__)) + "/" + name
67
+ end
68
+ end
data/test/leaktest.rb ADDED
@@ -0,0 +1,15 @@
1
+ require '../filemagic'
2
+
3
+ # watch -n 1 'ps aux | grep leaktest'
4
+
5
+ def do_file(filename)
6
+ fm = FileMagic.new(0)
7
+ file = fm.file(filename)
8
+ fm.close
9
+ return file
10
+ end
11
+
12
+ loop do
13
+ puts do_file($0)
14
+ sleep 1
15
+ end
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
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/ffi_file_magic')
5
+
6
+ class Test::Unit::TestCase
7
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: glongman-ffiruby-filemagic
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.3
5
+ platform: ruby
6
+ authors:
7
+ - Geoff Longman
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-21 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: ffi
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: new implementation of the ancient ruby-filemagic gem. Uses FFI to talk to native library
26
+ email: glongman@overlay.tv
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files: []
32
+
33
+ files:
34
+ - setup.rb
35
+ - LICENSE
36
+ - Rakefile
37
+ - README
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
42
+ - lib/ffi_file_magic.rb
43
+ - test/ffiruby_filemagic_test.rb
44
+ - test/leaktest.rb
45
+ - test/perl
46
+ - test/pyfile
47
+ - test/pyfile-compressed.gz
48
+ - test/test_helper.rb
49
+ has_rdoc: true
50
+ homepage: http://github.com/glongman/ffiruby-filemagic
51
+ post_install_message:
52
+ rdoc_options:
53
+ - --inline-source
54
+ - --charset=UTF-8
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.2.0
73
+ signing_key:
74
+ specification_version: 2
75
+ summary: new implementation of the ancient ruby-filemagic gem. Uses FFI to talk to native library
76
+ test_files: []
77
+