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 ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :patch: 0
3
+ :major: 0
4
+ :minor: 1
@@ -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
@@ -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,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
+