ruby-filemagic 0.2.1
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/CHANGELOG +28 -0
- data/README +69 -0
- data/Rakefile +26 -0
- data/TODO +9 -0
- data/ext/extconf.rb +8 -0
- data/ext/filemagic.c +213 -0
- data/info/example.rb +28 -0
- data/info/filemagic.rd +36 -0
- data/lib/filemagic.rb +177 -0
- data/lib/filemagic/ext.rb +95 -0
- data/lib/filemagic/version.rb +27 -0
- data/test/filemagic_test.rb +124 -0
- data/test/leaktest.rb +16 -0
- data/test/mahoro.c +187 -0
- data/test/perl +19 -0
- data/test/pyfile +1 -0
- data/test/pyfile-compressed.gz +0 -0
- data/test/pylink +1 -0
- metadata +80 -0
data/CHANGELOG
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
--------------------------------------------------------------------------------
|
2
|
+
7/28/2003 version 0.1.0
|
3
|
+
|
4
|
+
o Initial release.
|
5
|
+
|
6
|
+
--------------------------------------------------------------------------------
|
7
|
+
7/30/2003 version 0.1.1
|
8
|
+
|
9
|
+
o Added manual close method
|
10
|
+
o Added unit test suite
|
11
|
+
|
12
|
+
--------------------------------------------------------------------------------
|
13
|
+
9/12/2008 version 0.2.0
|
14
|
+
|
15
|
+
o Modified C API
|
16
|
+
o Uniform C function prefix rb_magic_ (instead of magick_)
|
17
|
+
o Uniform Ruby method prefix fm_ (instead of none)
|
18
|
+
o More magic(4) constants (if available)
|
19
|
+
o Added Ruby wrapper for more rubyish interface
|
20
|
+
o Added extensions for File and String core classes
|
21
|
+
o Added/updated project files
|
22
|
+
o Now available as a Rubygem!
|
23
|
+
|
24
|
+
--------------------------------------------------------------------------------
|
25
|
+
9/18/2008 version 0.2.1
|
26
|
+
|
27
|
+
o Added mahoro source file and tests for reference and inspiration
|
28
|
+
o We have a Rubyforge project now! :-)
|
data/README
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
= FileMagic Library Binding
|
2
|
+
|
3
|
+
== VERSION
|
4
|
+
|
5
|
+
This documentation refers to filemagic version 0.2.1
|
6
|
+
|
7
|
+
|
8
|
+
== DESCRIPTION
|
9
|
+
|
10
|
+
=== Revised version
|
11
|
+
|
12
|
+
September 12, 2008 Jens Wille <jens.wille@uni-koeln.de>
|
13
|
+
|
14
|
+
Similar to Ricardo[http://github.com/ricardochimal/ruby-filemagic]
|
15
|
+
I wanted this project to make some progress. My needs went a bit
|
16
|
+
farther than his, though ;-) Enjoy anyway!
|
17
|
+
|
18
|
+
Install the gem from github[http://github.com]:
|
19
|
+
|
20
|
+
sudo gem install blackwinter-ruby-filemagic --source http://gems.github.com
|
21
|
+
|
22
|
+
=== Original package
|
23
|
+
|
24
|
+
July 28, 2003 Travis Whitton <tinymountain@gmail.com>
|
25
|
+
|
26
|
+
This is one of my first ruby bindings, so suggestions are welcome. See
|
27
|
+
filemagic.rd and test.rb for usage.
|
28
|
+
|
29
|
+
to install, run these commands:
|
30
|
+
|
31
|
+
ruby extconf.rb
|
32
|
+
make
|
33
|
+
su
|
34
|
+
make install
|
35
|
+
|
36
|
+
the file(1) library and headers are required.
|
37
|
+
I have file 0.4.3.
|
38
|
+
|
39
|
+
Enjoy!
|
40
|
+
Travis
|
41
|
+
|
42
|
+
|
43
|
+
== LINKS
|
44
|
+
|
45
|
+
* <http://grub.ath.cx/filemagic/>
|
46
|
+
* <http://github.com/blackwinter/ruby-filemagic>
|
47
|
+
* <http://ruby-filemagic.rubyforge.org/>
|
48
|
+
* <http://rubyforge.org/projects/ruby-filemagic>
|
49
|
+
|
50
|
+
|
51
|
+
== AUTHORS
|
52
|
+
|
53
|
+
* Travis Whitton <mailto:tinymountain@gmail.com> (Original author)
|
54
|
+
* Jens Wille <mailto:jens.wille@uni-koeln.de>
|
55
|
+
|
56
|
+
|
57
|
+
== COPYING
|
58
|
+
|
59
|
+
The filemagic extension library is copywrited free software by Travis Whitton
|
60
|
+
<tinymountain@gmail.com>. You can redistribute it under the terms specified in
|
61
|
+
the COPYING file of the Ruby distribution.
|
62
|
+
|
63
|
+
|
64
|
+
== WARRANTY
|
65
|
+
|
66
|
+
THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
67
|
+
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
68
|
+
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
69
|
+
PURPOSE.
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require %q{lib/filemagic/version}
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'hen'
|
5
|
+
|
6
|
+
Hen.lay! {{
|
7
|
+
:rubyforge => {
|
8
|
+
:package => 'ruby-filemagic',
|
9
|
+
:project => 'ruby-filemagic',
|
10
|
+
:rdoc_dir => nil
|
11
|
+
},
|
12
|
+
|
13
|
+
:gem => {
|
14
|
+
:version => FileMagic::VERSION,
|
15
|
+
:summary => 'Ruby bindings to the magic(4) library',
|
16
|
+
:authors => ['Travis Whitton', 'Jens Wille'],
|
17
|
+
:email => ['tinymountain@gmail.com', 'jens.wille@uni-koeln.de'],
|
18
|
+
:homepage => 'http://ruby-filemagic.rubyforge.org/',
|
19
|
+
:files => FileList['lib/**/*.rb', 'ext/**/*.c', 'test/*'].to_a,
|
20
|
+
:extensions => FileList['ext/**/extconf.rb'].to_a,
|
21
|
+
:extra_files => FileList['[A-Z]*', 'info/*'].to_a
|
22
|
+
}
|
23
|
+
}}
|
24
|
+
rescue LoadError
|
25
|
+
abort "Please install the 'hen' gem first."
|
26
|
+
end
|
data/TODO
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
o Find a better way to handle magic_load than just defaulting to NULL
|
2
|
+
o Find a way to make magic_check work on NULL
|
3
|
+
o [DONE] Find a way to make magic_setflags work
|
4
|
+
o Refactor code into initialize instead of new
|
5
|
+
o [DONE?] Enable blocks for automatic cleanup:
|
6
|
+
|
7
|
+
FileMagic.open("somefile.txt") do |file|
|
8
|
+
# close is called at the end of this block
|
9
|
+
end
|
data/ext/extconf.rb
ADDED
data/ext/filemagic.c
ADDED
@@ -0,0 +1,213 @@
|
|
1
|
+
/*********************************************************
|
2
|
+
|
3
|
+
filemagic.c
|
4
|
+
|
5
|
+
a Ruby extension to bind Ruby to the libmagic library
|
6
|
+
(ftp://ftp.astron.com/pub/file/)
|
7
|
+
|
8
|
+
patterned very closely off of audiofile.c by jaredj which
|
9
|
+
is patterned very very closely off of gdbm.c by matz ;-)
|
10
|
+
|
11
|
+
$Author: twhitton $
|
12
|
+
$Date: 2003/07/30 13:25:10 $
|
13
|
+
|
14
|
+
*********************************************************/
|
15
|
+
|
16
|
+
#include "ruby.h"
|
17
|
+
#include <magic.h>
|
18
|
+
|
19
|
+
static VALUE cFileMagic, rb_FileMagicError;
|
20
|
+
|
21
|
+
#define GetMagicCookie(obj, cookie) {\
|
22
|
+
if (rb_funcall(obj, rb_intern("closed?"), 0))\
|
23
|
+
rb_raise(rb_eRuntimeError, "closed stream");\
|
24
|
+
Data_Get_Struct(obj, struct magic_set, cookie);\
|
25
|
+
}
|
26
|
+
|
27
|
+
/*
|
28
|
+
GC never seems to happen until the program terminates, but this is called
|
29
|
+
on any unclosed objects
|
30
|
+
*/
|
31
|
+
static void rb_magic_free(magic_t cookie) {
|
32
|
+
magic_close(cookie);
|
33
|
+
}
|
34
|
+
|
35
|
+
static VALUE rb_magic_init(VALUE self, VALUE flags) {
|
36
|
+
}
|
37
|
+
|
38
|
+
/* Frees resources allocated */
|
39
|
+
static VALUE rb_magic_close(VALUE self) {
|
40
|
+
magic_t cookie;
|
41
|
+
|
42
|
+
GetMagicCookie(self, cookie);
|
43
|
+
magic_close(cookie);
|
44
|
+
|
45
|
+
/* This keeps rb_magic_free from trying to free closed objects */
|
46
|
+
RDATA(self)->data = NULL;
|
47
|
+
|
48
|
+
return Qnil;
|
49
|
+
}
|
50
|
+
|
51
|
+
/* FileMagic.new */
|
52
|
+
static VALUE rb_magic_new(VALUE class, VALUE flags) {
|
53
|
+
VALUE obj;
|
54
|
+
magic_t cookie;
|
55
|
+
|
56
|
+
cookie = magic_open(NUM2INT(flags));
|
57
|
+
if (cookie == NULL)
|
58
|
+
rb_fatal("out of memory");
|
59
|
+
if (magic_load(cookie, NULL) == -1)
|
60
|
+
rb_fatal("%s", magic_error(cookie));
|
61
|
+
|
62
|
+
obj = Data_Wrap_Struct(class, 0, rb_magic_free, cookie);
|
63
|
+
rb_obj_call_init(obj, 1, &flags);
|
64
|
+
|
65
|
+
return obj;
|
66
|
+
}
|
67
|
+
|
68
|
+
/* Return a string describing file */
|
69
|
+
static VALUE rb_magic_file(VALUE self, VALUE file) {
|
70
|
+
const char *m;
|
71
|
+
magic_t cookie;
|
72
|
+
|
73
|
+
m = STR2CSTR(file);
|
74
|
+
GetMagicCookie(self, cookie);
|
75
|
+
if ((m = magic_file(cookie, m)) == NULL)
|
76
|
+
rb_raise(rb_FileMagicError, magic_error(cookie));
|
77
|
+
|
78
|
+
return rb_str_new2(m);
|
79
|
+
}
|
80
|
+
|
81
|
+
/* Return a string describing the string buffer */
|
82
|
+
static VALUE rb_magic_buffer(VALUE self, VALUE buffer) {
|
83
|
+
int i = RSTRING(buffer)->len;
|
84
|
+
const char *m;
|
85
|
+
magic_t cookie;
|
86
|
+
|
87
|
+
m = STR2CSTR(buffer);
|
88
|
+
GetMagicCookie(self, cookie);
|
89
|
+
if ((m = magic_buffer(cookie, m, i)) == NULL)
|
90
|
+
rb_raise(rb_FileMagicError, magic_error(cookie));
|
91
|
+
|
92
|
+
return rb_str_new2(m);
|
93
|
+
}
|
94
|
+
|
95
|
+
/* Set flags on the cookie object */
|
96
|
+
static VALUE rb_magic_setflags(VALUE self, VALUE flags) {
|
97
|
+
int retval;
|
98
|
+
magic_t cookie;
|
99
|
+
|
100
|
+
GetMagicCookie(self, cookie);
|
101
|
+
retval = magic_setflags(cookie, NUM2INT(flags));
|
102
|
+
|
103
|
+
return INT2FIX(retval);
|
104
|
+
}
|
105
|
+
|
106
|
+
/* Checks validity of a magic database file */
|
107
|
+
static VALUE rb_magic_check(VALUE self, VALUE file) {
|
108
|
+
int retval;
|
109
|
+
const char *m;
|
110
|
+
magic_t cookie;
|
111
|
+
|
112
|
+
GetMagicCookie(self, cookie);
|
113
|
+
m = STR2CSTR(file);
|
114
|
+
retval = magic_check(cookie, m);
|
115
|
+
|
116
|
+
return INT2FIX(retval);
|
117
|
+
}
|
118
|
+
|
119
|
+
/* Compiles a magic database file */
|
120
|
+
static VALUE rb_magic_compile(VALUE self, VALUE file) {
|
121
|
+
int retval;
|
122
|
+
const char *m;
|
123
|
+
magic_t cookie;
|
124
|
+
|
125
|
+
GetMagicCookie(self, cookie);
|
126
|
+
m = STR2CSTR(file);
|
127
|
+
retval = magic_compile(cookie, m);
|
128
|
+
|
129
|
+
return INT2FIX(retval);
|
130
|
+
}
|
131
|
+
|
132
|
+
void Init_filemagic() {
|
133
|
+
cFileMagic = rb_define_class("FileMagic", rb_cObject);
|
134
|
+
|
135
|
+
rb_define_singleton_method(cFileMagic, "fm_new", rb_magic_new, 1);
|
136
|
+
|
137
|
+
rb_define_method(cFileMagic, "fm_initialize", rb_magic_init, 1);
|
138
|
+
rb_define_method(cFileMagic, "fm_close", rb_magic_close, 0);
|
139
|
+
rb_define_method(cFileMagic, "fm_file", rb_magic_file, 1);
|
140
|
+
rb_define_method(cFileMagic, "fm_buffer", rb_magic_buffer, 1);
|
141
|
+
rb_define_method(cFileMagic, "fm_setflags", rb_magic_setflags, 1);
|
142
|
+
rb_define_method(cFileMagic, "fm_check", rb_magic_check, 1);
|
143
|
+
rb_define_method(cFileMagic, "fm_compile", rb_magic_compile, 1);
|
144
|
+
|
145
|
+
rb_FileMagicError = rb_define_class_under(cFileMagic, "FileMagicError", rb_eStandardError);
|
146
|
+
|
147
|
+
#ifdef MAGIC_NONE
|
148
|
+
rb_define_const(cFileMagic, "MAGIC_NONE", INT2FIX(MAGIC_NONE));
|
149
|
+
#endif
|
150
|
+
#ifdef MAGIC_DEBUG
|
151
|
+
rb_define_const(cFileMagic, "MAGIC_DEBUG", INT2FIX(MAGIC_DEBUG));
|
152
|
+
#endif
|
153
|
+
#ifdef MAGIC_SYMLINK
|
154
|
+
rb_define_const(cFileMagic, "MAGIC_SYMLINK", INT2FIX(MAGIC_SYMLINK));
|
155
|
+
#endif
|
156
|
+
#ifdef MAGIC_COMPRESS
|
157
|
+
rb_define_const(cFileMagic, "MAGIC_COMPRESS", INT2FIX(MAGIC_COMPRESS));
|
158
|
+
#endif
|
159
|
+
#ifdef MAGIC_DEVICES
|
160
|
+
rb_define_const(cFileMagic, "MAGIC_DEVICES", INT2FIX(MAGIC_DEVICES));
|
161
|
+
#endif
|
162
|
+
#ifdef MAGIC_MIME_TYPE
|
163
|
+
rb_define_const(cFileMagic, "MAGIC_MIME_TYPE", INT2FIX(MAGIC_MIME_TYPE));
|
164
|
+
#endif
|
165
|
+
#ifdef MAGIC_CONTINUE
|
166
|
+
rb_define_const(cFileMagic, "MAGIC_CONTINUE", INT2FIX(MAGIC_CONTINUE));
|
167
|
+
#endif
|
168
|
+
#ifdef MAGIC_CHECK
|
169
|
+
rb_define_const(cFileMagic, "MAGIC_CHECK", INT2FIX(MAGIC_CHECK));
|
170
|
+
#endif
|
171
|
+
#ifdef MAGIC_PRESERVE_ATIME
|
172
|
+
rb_define_const(cFileMagic, "MAGIC_PRESERVE_ATIME", INT2FIX(MAGIC_PRESERVE_ATIME));
|
173
|
+
#endif
|
174
|
+
#ifdef MAGIC_RAW
|
175
|
+
rb_define_const(cFileMagic, "MAGIC_RAW", INT2FIX(MAGIC_RAW));
|
176
|
+
#endif
|
177
|
+
#ifdef MAGIC_ERROR
|
178
|
+
rb_define_const(cFileMagic, "MAGIC_ERROR", INT2FIX(MAGIC_ERROR));
|
179
|
+
#endif
|
180
|
+
#ifdef MAGIC_MIME_ENCODING
|
181
|
+
rb_define_const(cFileMagic, "MAGIC_MIME_ENCODING", INT2FIX(MAGIC_MIME_ENCODING));
|
182
|
+
#endif
|
183
|
+
#ifdef MAGIC_MIME
|
184
|
+
rb_define_const(cFileMagic, "MAGIC_MIME", INT2FIX(MAGIC_MIME));
|
185
|
+
#endif
|
186
|
+
#ifdef MAGIC_NO_CHECK_COMPRESS
|
187
|
+
rb_define_const(cFileMagic, "MAGIC_NO_CHECK_COMPRESS", INT2FIX(MAGIC_NO_CHECK_COMPRESS));
|
188
|
+
#endif
|
189
|
+
#ifdef MAGIC_NO_CHECK_TAR
|
190
|
+
rb_define_const(cFileMagic, "MAGIC_NO_CHECK_TAR", INT2FIX(MAGIC_NO_CHECK_TAR));
|
191
|
+
#endif
|
192
|
+
#ifdef MAGIC_NO_CHECK_SOFT
|
193
|
+
rb_define_const(cFileMagic, "MAGIC_NO_CHECK_SOFT", INT2FIX(MAGIC_NO_CHECK_SOFT));
|
194
|
+
#endif
|
195
|
+
#ifdef MAGIC_NO_CHECK_APPTYPE
|
196
|
+
rb_define_const(cFileMagic, "MAGIC_NO_CHECK_APPTYPE", INT2FIX(MAGIC_NO_CHECK_APPTYPE));
|
197
|
+
#endif
|
198
|
+
#ifdef MAGIC_NO_CHECK_ELF
|
199
|
+
rb_define_const(cFileMagic, "MAGIC_NO_CHECK_ELF", INT2FIX(MAGIC_NO_CHECK_ELF));
|
200
|
+
#endif
|
201
|
+
#ifdef MAGIC_NO_CHECK_ASCII
|
202
|
+
rb_define_const(cFileMagic, "MAGIC_NO_CHECK_ASCII", INT2FIX(MAGIC_NO_CHECK_ASCII));
|
203
|
+
#endif
|
204
|
+
#ifdef MAGIC_NO_CHECK_TROFF
|
205
|
+
rb_define_const(cFileMagic, "MAGIC_NO_CHECK_TROFF", INT2FIX(MAGIC_NO_CHECK_TROFF));
|
206
|
+
#endif
|
207
|
+
#ifdef MAGIC_NO_CHECK_TOKENS
|
208
|
+
rb_define_const(cFileMagic, "MAGIC_NO_CHECK_TOKENS", INT2FIX(MAGIC_NO_CHECK_TOKENS));
|
209
|
+
#endif
|
210
|
+
#ifdef MAGIC_NO_CHECK_FORTRAN
|
211
|
+
rb_define_const(cFileMagic, "MAGIC_NO_CHECK_FORTRAN", INT2FIX(MAGIC_NO_CHECK_FORTRAN));
|
212
|
+
#endif
|
213
|
+
}
|
data/info/example.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
|
3
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
4
|
+
require 'filemagic'
|
5
|
+
|
6
|
+
puts FileMagic.new.flags
|
7
|
+
|
8
|
+
FileMagic.open(:mime) { |fm|
|
9
|
+
puts fm.flags
|
10
|
+
puts fm.file(__FILE__)
|
11
|
+
|
12
|
+
fm.setflags(:raw, :continue)
|
13
|
+
puts fm.flags
|
14
|
+
}
|
15
|
+
|
16
|
+
fm = FileMagic.new
|
17
|
+
puts fm.flags
|
18
|
+
|
19
|
+
mime = FileMagic.mime
|
20
|
+
puts mime.flags
|
21
|
+
|
22
|
+
ARGV.each { |file|
|
23
|
+
puts fm.file(file)
|
24
|
+
puts fm.file(file, true)
|
25
|
+
|
26
|
+
puts mime.file(file)
|
27
|
+
puts mime.file(file, true)
|
28
|
+
}
|
data/info/filemagic.rd
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
= FileMagic extension module SEE ALSO libmagic(3), file(1) and magic(4)
|
4
|
+
== FileMagic
|
5
|
+
=== Constants
|
6
|
+
: MAGIC_NONE
|
7
|
+
No flags
|
8
|
+
: MAGIC_DEBUG
|
9
|
+
Turn on debuggin
|
10
|
+
: MAGIC_SYMLINK
|
11
|
+
Follow symlinks
|
12
|
+
: MAGIC_COMPRESS
|
13
|
+
Check inside compressed files
|
14
|
+
: MAGIC_DEVICES
|
15
|
+
Look at the contents of devices
|
16
|
+
: MAGIC_MIME
|
17
|
+
Return a mime string
|
18
|
+
: MAGIC_CONTINUE
|
19
|
+
Return all matches, not just the first
|
20
|
+
: MAGIC_CHECK
|
21
|
+
Print warnings to stderr
|
22
|
+
|
23
|
+
=== Methods
|
24
|
+
: file(filename)
|
25
|
+
returns a textual description of the contents of the filename argument
|
26
|
+
: buffer(string)
|
27
|
+
returns a textual description of the contents of the string argument
|
28
|
+
: check(filename)
|
29
|
+
checks the validity of entries in the colon separated database files
|
30
|
+
passed in as filename
|
31
|
+
: compile(filename)
|
32
|
+
compile the the colon separated list of database files passed in as
|
33
|
+
filename
|
34
|
+
: close()
|
35
|
+
closes the magic database and frees any memory allocated. if memory
|
36
|
+
is a concern, use this.
|
data/lib/filemagic.rb
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
require 'filemagic.so'
|
2
|
+
|
3
|
+
class FileMagic
|
4
|
+
|
5
|
+
# Map abbreviated flag names to their values (:name => Constant).
|
6
|
+
MAGIC_FLAGS = [
|
7
|
+
:none, # No flags
|
8
|
+
:debug, # Turn on debugging
|
9
|
+
:symlink, # Follow symlinks
|
10
|
+
:compress, # Check inside compressed files
|
11
|
+
:devices, # Look at the contents of devices
|
12
|
+
:mime_type, # Return only the MIME type
|
13
|
+
:continue, # Return all matches
|
14
|
+
:check, # Print warnings to stderr
|
15
|
+
:preserve_atime, # Restore access time on exit
|
16
|
+
:raw, # Don't translate unprint chars
|
17
|
+
:error, # Handle ENOENT etc as real errors
|
18
|
+
:mime_encoding, # Return only the MIME encoding
|
19
|
+
:mime, # MAGIC_MIME_TYPE | MAGIC_MIME_ENCODING
|
20
|
+
:no_check_compress, # Don't check for compressed files
|
21
|
+
:no_check_tar, # Don't check for tar files
|
22
|
+
:no_check_soft, # Don't check magic entries
|
23
|
+
:no_check_apptype, # Don't check application type
|
24
|
+
:no_check_elf, # Don't check for elf details
|
25
|
+
:no_check_ascii, # Don't check for ascii files
|
26
|
+
:no_check_troff, # Don't check ascii/troff
|
27
|
+
:no_check_tokens, # Don't check ascii/tokens
|
28
|
+
:no_check_fortran # Don't check ascii/fortran
|
29
|
+
].inject({}) { |flags, flag|
|
30
|
+
const = "MAGIC_#{flag.to_s.upcase}"
|
31
|
+
flags.update(flag => const_defined?(const) && const_get(const))
|
32
|
+
}
|
33
|
+
|
34
|
+
attr_reader :flags
|
35
|
+
attr_writer :simplified
|
36
|
+
|
37
|
+
@fm = Hash.new { |fm, flags|
|
38
|
+
fm.has_key?(key = flags.to_s) ? fm[key] : fm[key] = new(*flags)
|
39
|
+
}
|
40
|
+
|
41
|
+
class << self
|
42
|
+
|
43
|
+
# Provide a "magic singleton" ;-)
|
44
|
+
def fm(*flags)
|
45
|
+
@fm.delete(flags.to_s) if @fm[flags].closed?
|
46
|
+
@fm[flags]
|
47
|
+
end
|
48
|
+
|
49
|
+
# Clear our instance cache.
|
50
|
+
def clear!
|
51
|
+
@fm.each_value { |fm| fm.close }
|
52
|
+
@fm.clear
|
53
|
+
end
|
54
|
+
|
55
|
+
# Allow shorter names for flags; now also takes options.
|
56
|
+
def new(*flags)
|
57
|
+
warn "warning: FileMagic::new() does not take block; use FileMagic::open() instead" if block_given?
|
58
|
+
|
59
|
+
options = flags.last.is_a?(Hash) ? flags.pop : {}
|
60
|
+
|
61
|
+
fm = fm_new(build_flags(*flags))
|
62
|
+
|
63
|
+
options.each { |option, value|
|
64
|
+
if fm.respond_to?(method = "#{option}=")
|
65
|
+
fm.send(method, value)
|
66
|
+
else
|
67
|
+
raise ArgumentError, "illegal option: #{option.inspect}"
|
68
|
+
end
|
69
|
+
}
|
70
|
+
|
71
|
+
fm
|
72
|
+
end
|
73
|
+
|
74
|
+
# Just like #new, but takes an optional block, in which case #close is called at the end.
|
75
|
+
def open(*flags)
|
76
|
+
fm = new(*flags)
|
77
|
+
|
78
|
+
if block_given?
|
79
|
+
begin
|
80
|
+
yield fm
|
81
|
+
ensure
|
82
|
+
fm.close
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
fm
|
87
|
+
end
|
88
|
+
|
89
|
+
# Just a short-cut ;-)
|
90
|
+
def mime(*flags, &block)
|
91
|
+
open(:mime, *flags, &block)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Build the actual flags from the named flags passed as arguments.
|
95
|
+
def build_flags(*flags)
|
96
|
+
_flags = *flags
|
97
|
+
|
98
|
+
unless _flags.is_a?(Integer)
|
99
|
+
_flags = MAGIC_NONE
|
100
|
+
|
101
|
+
flags.flatten.each { |flag|
|
102
|
+
if value = flag.is_a?(Integer) ? flag : MAGIC_FLAGS[flag.to_sym]
|
103
|
+
_flags |= value
|
104
|
+
else
|
105
|
+
raise ArgumentError, "#{value.nil? ? 'no such flag' : 'flag not available'}: #{flag}"
|
106
|
+
end
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
_flags
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
# The actual processing happens in #new.
|
116
|
+
def initialize(*flags)
|
117
|
+
fm_initialize(*flags)
|
118
|
+
|
119
|
+
@flags = *flags
|
120
|
+
@closed = false
|
121
|
+
end
|
122
|
+
|
123
|
+
def close
|
124
|
+
return if closed?
|
125
|
+
|
126
|
+
fm_close
|
127
|
+
@closed = true
|
128
|
+
end
|
129
|
+
|
130
|
+
# Optionally cut off additional information after mime-type.
|
131
|
+
def file(file, simplified = simplified?)
|
132
|
+
simplify_mime(fm_file(file), simplified)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Optionally cut off additional information after mime-type.
|
136
|
+
def buffer(buffer, simplified = simplified?)
|
137
|
+
simplify_mime(fm_buffer(buffer), simplified)
|
138
|
+
end
|
139
|
+
|
140
|
+
def setflags(*flags)
|
141
|
+
previous_flags, @flags = @flags, self.class.build_flags(*flags)
|
142
|
+
fm_setflags(@flags)
|
143
|
+
|
144
|
+
previous_flags
|
145
|
+
end
|
146
|
+
alias_method :flags=, :setflags
|
147
|
+
|
148
|
+
def check(file = "\0")
|
149
|
+
fm_check(file)
|
150
|
+
end
|
151
|
+
alias_method :valid?, :check
|
152
|
+
|
153
|
+
def compile(file)
|
154
|
+
fm_compile(file)
|
155
|
+
end
|
156
|
+
|
157
|
+
def simplified?
|
158
|
+
@simplified
|
159
|
+
end
|
160
|
+
|
161
|
+
def closed?
|
162
|
+
@closed
|
163
|
+
end
|
164
|
+
|
165
|
+
def inspect
|
166
|
+
str = super
|
167
|
+
str.insert(-2, ' (closed)') if closed?
|
168
|
+
str
|
169
|
+
end
|
170
|
+
|
171
|
+
private
|
172
|
+
|
173
|
+
def simplify_mime(mime, simplified = true)
|
174
|
+
simplified ? mime[/([\w\/-]+)/, 1].downcase : mime
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'filemagic'
|
2
|
+
|
3
|
+
module FileMagic::Ext
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
|
7
|
+
def file_type(file, *flags)
|
8
|
+
raise NotImplementedError, 'must be implemented by including class'
|
9
|
+
end
|
10
|
+
|
11
|
+
def file(file, *flags)
|
12
|
+
file_type(file, *flags)
|
13
|
+
end
|
14
|
+
|
15
|
+
def mime_type(file, *flags)
|
16
|
+
flags.unshift :mime
|
17
|
+
file_type(file, *flags)
|
18
|
+
end
|
19
|
+
alias_method :mime, :mime_type
|
20
|
+
|
21
|
+
def content_type(file, *flags)
|
22
|
+
flags << { :simplified => true }
|
23
|
+
mime_type(file, *flags)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
module InstanceMethods
|
29
|
+
|
30
|
+
def file_type(*flags)
|
31
|
+
self.class.file_type(self, *flags)
|
32
|
+
end
|
33
|
+
alias_method :file, :file_type
|
34
|
+
|
35
|
+
def mime_type(*flags)
|
36
|
+
self.class.mime_type(self, *flags)
|
37
|
+
end
|
38
|
+
alias_method :mime, :mime_type
|
39
|
+
|
40
|
+
def content_type(*flags)
|
41
|
+
self.class.content_type(self, *flags)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
class File
|
49
|
+
|
50
|
+
include FileMagic::Ext::InstanceMethods
|
51
|
+
extend FileMagic::Ext::ClassMethods
|
52
|
+
|
53
|
+
def self.file_type(file, *flags)
|
54
|
+
FileMagic.fm(*flags).file(file.respond_to?(:path) ? file.path : file)
|
55
|
+
rescue FileMagic::FileMagicError
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
class String
|
62
|
+
|
63
|
+
include FileMagic::Ext::InstanceMethods
|
64
|
+
extend FileMagic::Ext::ClassMethods
|
65
|
+
|
66
|
+
def self.file_type(string, *flags)
|
67
|
+
FileMagic.fm(*flags).buffer(string)
|
68
|
+
rescue FileMagic::FileMagicError
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
if $0 == __FILE__
|
75
|
+
f = __FILE__
|
76
|
+
p f
|
77
|
+
|
78
|
+
p File.file_type(f)
|
79
|
+
p File.mime_type(f)
|
80
|
+
p File.content_type(f)
|
81
|
+
|
82
|
+
f = File.new(f)
|
83
|
+
p f
|
84
|
+
|
85
|
+
p f.file_type
|
86
|
+
p f.mime_type
|
87
|
+
p f.content_type
|
88
|
+
|
89
|
+
s = '#! /usr/bin/ruby'
|
90
|
+
p s
|
91
|
+
|
92
|
+
p s.file_type
|
93
|
+
p s.mime_type
|
94
|
+
p s.content_type
|
95
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class FileMagic
|
2
|
+
|
3
|
+
module Version
|
4
|
+
|
5
|
+
MAJOR = 0
|
6
|
+
MINOR = 2
|
7
|
+
TINY = 1
|
8
|
+
|
9
|
+
class << self
|
10
|
+
|
11
|
+
# Returns array representation.
|
12
|
+
def to_a
|
13
|
+
[MAJOR, MINOR, TINY]
|
14
|
+
end
|
15
|
+
|
16
|
+
# Short-cut for version string.
|
17
|
+
def to_s
|
18
|
+
to_a.join('.')
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
VERSION = Version.to_s
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
4
|
+
require 'filemagic'
|
5
|
+
|
6
|
+
class TestFileMagic < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def test_file
|
9
|
+
fm = FileMagic.new(FileMagic::MAGIC_NONE)
|
10
|
+
|
11
|
+
res = fm.file(path_to('pyfile'))
|
12
|
+
assert_equal('a python script text executable', res)
|
13
|
+
|
14
|
+
if File.symlink?(path_to('pylink'))
|
15
|
+
res = fm.file(path_to('pylink'))
|
16
|
+
assert_equal("symbolic link to `pyfile'", res)
|
17
|
+
end
|
18
|
+
|
19
|
+
fm.close
|
20
|
+
fm = FileMagic.new(FileMagic::MAGIC_SYMLINK)
|
21
|
+
|
22
|
+
res = fm.file(path_to('pylink'))
|
23
|
+
assert_equal('a python script text executable', res)
|
24
|
+
|
25
|
+
fm.close
|
26
|
+
fm = FileMagic.new(FileMagic::MAGIC_SYMLINK | FileMagic::MAGIC_MIME)
|
27
|
+
|
28
|
+
res = fm.file(path_to('pylink'))
|
29
|
+
assert_equal('text/plain; charset=us-ascii', res)
|
30
|
+
|
31
|
+
fm.close
|
32
|
+
fm = FileMagic.new(FileMagic::MAGIC_COMPRESS)
|
33
|
+
|
34
|
+
res = fm.file(path_to('pyfile-compressed.gz'))
|
35
|
+
assert_match(/^a python script text executable \(gzip compressed data, was "pyfile-compressed", from Unix/, res)
|
36
|
+
|
37
|
+
fm.close
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_buffer
|
41
|
+
fm = FileMagic.new(FileMagic::MAGIC_NONE)
|
42
|
+
res = fm.buffer("#!/bin/sh\n")
|
43
|
+
fm.close
|
44
|
+
assert_match(/shell script text executable$/, res)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_check
|
48
|
+
fm = FileMagic.new(FileMagic::MAGIC_NONE)
|
49
|
+
res = fm.check(path_to('perl'))
|
50
|
+
fm.close
|
51
|
+
assert_equal(0, res)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_compile
|
55
|
+
assert(File.writable?('.'), "can't write to current directory")
|
56
|
+
fm = FileMagic.new(FileMagic::MAGIC_NONE)
|
57
|
+
res = fm.compile(path_to('perl'))
|
58
|
+
fm.close
|
59
|
+
assert_equal(0, res)
|
60
|
+
File.unlink(path_to('perl.mgc', '.'))
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_block
|
64
|
+
block_fm = FileMagic.open(FileMagic::MAGIC_NONE) { |fm|
|
65
|
+
res = fm.file(path_to('pyfile'))
|
66
|
+
assert_equal('a python script text executable', res)
|
67
|
+
}
|
68
|
+
assert block_fm.closed?
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_setflags
|
72
|
+
fm = FileMagic.new(FileMagic::MAGIC_NONE)
|
73
|
+
assert_equal(FileMagic::MAGIC_NONE, fm.flags)
|
74
|
+
fm.setflags(FileMagic::MAGIC_SYMLINK)
|
75
|
+
assert_equal(FileMagic::MAGIC_SYMLINK, fm.flags)
|
76
|
+
fm.close
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_abbr
|
80
|
+
fm = FileMagic.new(:mime, :continue)
|
81
|
+
assert_equal(FileMagic::MAGIC_MIME | FileMagic::MAGIC_CONTINUE, fm.flags)
|
82
|
+
fm.setflags(:symlink)
|
83
|
+
assert_equal(FileMagic::MAGIC_SYMLINK, fm.flags)
|
84
|
+
fm.close
|
85
|
+
end
|
86
|
+
|
87
|
+
# tests adapted from mahoro:
|
88
|
+
|
89
|
+
def test_mahoro_file
|
90
|
+
fm = FileMagic.new
|
91
|
+
fm.flags = FileMagic::MAGIC_NONE
|
92
|
+
assert_equal('ASCII C program text', fm.file(path_to('mahoro.c')))
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_mahoro_mime_file
|
96
|
+
fm = FileMagic.new
|
97
|
+
fm.flags = FileMagic::MAGIC_MIME
|
98
|
+
assert_equal('text/x-c; charset=us-ascii', fm.file(path_to('mahoro.c')))
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_mahoro_buffer
|
102
|
+
fm = FileMagic.new
|
103
|
+
fm.flags = FileMagic::MAGIC_NONE
|
104
|
+
assert_equal('ASCII C program text', fm.buffer(File.read(path_to('mahoro.c'))))
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_mahoro_mime_buffer
|
108
|
+
fm = FileMagic.new
|
109
|
+
fm.flags = FileMagic::MAGIC_MIME
|
110
|
+
assert_equal('text/x-c; charset=us-ascii', fm.buffer(File.read(path_to('mahoro.c'))))
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_mahoro_valid
|
114
|
+
fm = FileMagic.new
|
115
|
+
assert(fm.valid?, 'Default database was not valid.')
|
116
|
+
end
|
117
|
+
|
118
|
+
# utility methods:
|
119
|
+
|
120
|
+
def path_to(file, dir = File.dirname(__FILE__))
|
121
|
+
File.join(dir, file)
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
data/test/leaktest.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
require 'filemagic'
|
3
|
+
|
4
|
+
warn "watch -n 1 'ps aux | grep [l]eaktest'"
|
5
|
+
|
6
|
+
def do_file(filename)
|
7
|
+
fm = FileMagic.new(0)
|
8
|
+
file = fm.file(filename)
|
9
|
+
fm.close
|
10
|
+
return file
|
11
|
+
end
|
12
|
+
|
13
|
+
loop do
|
14
|
+
puts do_file($0)
|
15
|
+
sleep 1
|
16
|
+
end
|
data/test/mahoro.c
ADDED
@@ -0,0 +1,187 @@
|
|
1
|
+
/*
|
2
|
+
* This file is Public Domain.
|
3
|
+
*/
|
4
|
+
|
5
|
+
#include <ruby.h>
|
6
|
+
#include <magic.h>
|
7
|
+
|
8
|
+
struct MagicCookie
|
9
|
+
{
|
10
|
+
magic_t cookie;
|
11
|
+
};
|
12
|
+
|
13
|
+
static VALUE cMahoro;
|
14
|
+
static VALUE eMahoroError;
|
15
|
+
|
16
|
+
static void
|
17
|
+
mahoro_free(ptr)
|
18
|
+
struct MagicCookie *ptr;
|
19
|
+
{
|
20
|
+
magic_close(ptr->cookie);
|
21
|
+
free(ptr);
|
22
|
+
}
|
23
|
+
|
24
|
+
static VALUE
|
25
|
+
mahoro_allocate(klass)
|
26
|
+
VALUE klass;
|
27
|
+
{
|
28
|
+
return Data_Wrap_Struct(klass, 0, mahoro_free, 0);
|
29
|
+
}
|
30
|
+
|
31
|
+
static VALUE
|
32
|
+
mahoro_initialize(argc, argv, self)
|
33
|
+
int argc;
|
34
|
+
VALUE *argv, self;
|
35
|
+
{
|
36
|
+
int flags = MAGIC_NONE;
|
37
|
+
char *path = 0;
|
38
|
+
struct MagicCookie *ptr;
|
39
|
+
magic_t cookie;
|
40
|
+
VALUE vpath, vflags;
|
41
|
+
|
42
|
+
switch(rb_scan_args(argc, argv, "02", &vflags, &vpath)) {
|
43
|
+
case 2:
|
44
|
+
if(!NIL_P(vpath)) {
|
45
|
+
path = StringValuePtr(vpath);
|
46
|
+
}
|
47
|
+
/* fallthrough */
|
48
|
+
case 1:
|
49
|
+
flags = FIX2INT(vflags);
|
50
|
+
break;
|
51
|
+
}
|
52
|
+
|
53
|
+
if(!(cookie = magic_open(flags))) {
|
54
|
+
rb_raise(eMahoroError, "failed to initialize magic cookie");
|
55
|
+
}
|
56
|
+
|
57
|
+
if(magic_load(cookie, path)) {
|
58
|
+
rb_raise(eMahoroError, "failed to load database: %s",
|
59
|
+
magic_error(cookie));
|
60
|
+
}
|
61
|
+
|
62
|
+
ptr = ALLOC(struct MagicCookie);
|
63
|
+
ptr->cookie = cookie;
|
64
|
+
DATA_PTR(self) = ptr;
|
65
|
+
|
66
|
+
return self;
|
67
|
+
}
|
68
|
+
|
69
|
+
static VALUE
|
70
|
+
mahoro_file(self, path)
|
71
|
+
VALUE self, path;
|
72
|
+
{
|
73
|
+
const char *msg;
|
74
|
+
magic_t cookie = ((struct MagicCookie *) DATA_PTR(self))->cookie;
|
75
|
+
|
76
|
+
if(!(msg = magic_file(cookie, StringValuePtr(path)))) {
|
77
|
+
rb_raise(eMahoroError, "failed lookup: %s", magic_error(cookie));
|
78
|
+
}
|
79
|
+
|
80
|
+
return rb_str_new2(msg);
|
81
|
+
}
|
82
|
+
|
83
|
+
static VALUE
|
84
|
+
mahoro_buffer(self, input)
|
85
|
+
VALUE self, input;
|
86
|
+
{
|
87
|
+
const char *msg;
|
88
|
+
magic_t cookie = ((struct MagicCookie *) DATA_PTR(self))->cookie;
|
89
|
+
|
90
|
+
if(!(msg = magic_buffer(cookie, StringValuePtr(input),
|
91
|
+
RSTRING(StringValue(input))->len))) {
|
92
|
+
rb_raise(eMahoroError, "failed lookup: %s", magic_error(cookie));
|
93
|
+
}
|
94
|
+
|
95
|
+
return rb_str_new2(msg);
|
96
|
+
}
|
97
|
+
|
98
|
+
static VALUE
|
99
|
+
mahoro_set_flags(self, flags)
|
100
|
+
VALUE self, flags;
|
101
|
+
{
|
102
|
+
magic_t cookie = ((struct MagicCookie *) DATA_PTR(self))->cookie;
|
103
|
+
|
104
|
+
return INT2FIX(magic_setflags(cookie, FIX2INT(flags)));
|
105
|
+
}
|
106
|
+
|
107
|
+
static VALUE
|
108
|
+
mahoro_check(argc, argv, self)
|
109
|
+
int argc;
|
110
|
+
VALUE *argv, self;
|
111
|
+
{
|
112
|
+
char *path = 0;
|
113
|
+
VALUE vpath;
|
114
|
+
magic_t cookie = ((struct MagicCookie *) DATA_PTR(self))->cookie;
|
115
|
+
|
116
|
+
switch(rb_scan_args(argc, argv, "01", &vpath)) {
|
117
|
+
case 1:
|
118
|
+
if(!NIL_P(vpath)) {
|
119
|
+
path = StringValuePtr(vpath);
|
120
|
+
}
|
121
|
+
break;
|
122
|
+
}
|
123
|
+
|
124
|
+
if(!magic_check(cookie, path)) {
|
125
|
+
return Qtrue;
|
126
|
+
} else {
|
127
|
+
return Qfalse;
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
131
|
+
static VALUE
|
132
|
+
mahoro_compile(klass, path)
|
133
|
+
VALUE klass, path;
|
134
|
+
{
|
135
|
+
magic_t cookie = magic_open(MAGIC_NONE);
|
136
|
+
|
137
|
+
if(magic_compile(cookie, StringValuePtr(path))) {
|
138
|
+
rb_raise(eMahoroError, "failed compile: %s", magic_error(cookie));
|
139
|
+
}
|
140
|
+
|
141
|
+
magic_close(cookie);
|
142
|
+
|
143
|
+
return Qtrue;
|
144
|
+
}
|
145
|
+
|
146
|
+
static VALUE
|
147
|
+
mahoro_load(self, path)
|
148
|
+
VALUE self, path;
|
149
|
+
{
|
150
|
+
magic_t cookie = ((struct MagicCookie *) DATA_PTR(self))->cookie;
|
151
|
+
|
152
|
+
if(magic_load(cookie, StringValuePtr(path))) {
|
153
|
+
rb_raise(eMahoroError, "failed load: %s", magic_error(cookie));
|
154
|
+
}
|
155
|
+
|
156
|
+
return self;
|
157
|
+
}
|
158
|
+
|
159
|
+
void Init_mahoro(void)
|
160
|
+
{
|
161
|
+
cMahoro = rb_define_class("Mahoro", rb_cObject);
|
162
|
+
eMahoroError = rb_define_class_under(cMahoro, "Error", rb_eStandardError);
|
163
|
+
|
164
|
+
rb_const_set(cMahoro, rb_intern("NONE"), INT2FIX(MAGIC_NONE));
|
165
|
+
rb_const_set(cMahoro, rb_intern("DEBUG"), INT2FIX(MAGIC_DEBUG));
|
166
|
+
rb_const_set(cMahoro, rb_intern("SYMLINK"), INT2FIX(MAGIC_SYMLINK));
|
167
|
+
rb_const_set(cMahoro, rb_intern("COMPRESS"), INT2FIX(MAGIC_COMPRESS));
|
168
|
+
rb_const_set(cMahoro, rb_intern("DEVICES"), INT2FIX(MAGIC_DEVICES));
|
169
|
+
rb_const_set(cMahoro, rb_intern("MIME"), INT2FIX(MAGIC_MIME));
|
170
|
+
rb_const_set(cMahoro, rb_intern("CONTINUE"), INT2FIX(MAGIC_CONTINUE));
|
171
|
+
rb_const_set(cMahoro, rb_intern("CHECK"), INT2FIX(MAGIC_CHECK));
|
172
|
+
rb_const_set(cMahoro, rb_intern("PRESERVE_ATIME"),
|
173
|
+
INT2FIX(MAGIC_PRESERVE_ATIME));
|
174
|
+
rb_const_set(cMahoro, rb_intern("RAW"), INT2FIX(MAGIC_RAW));
|
175
|
+
rb_const_set(cMahoro, rb_intern("ERROR"), INT2FIX(MAGIC_ERROR));
|
176
|
+
|
177
|
+
rb_define_alloc_func(cMahoro, mahoro_allocate);
|
178
|
+
rb_define_method(cMahoro, "initialize", mahoro_initialize, -1);
|
179
|
+
rb_define_method(cMahoro, "file", mahoro_file, 1);
|
180
|
+
rb_define_method(cMahoro, "buffer", mahoro_buffer, 1);
|
181
|
+
rb_define_method(cMahoro, "flags=", mahoro_set_flags, 1);
|
182
|
+
rb_define_method(cMahoro, "valid?", mahoro_check, -1);
|
183
|
+
rb_define_singleton_method(cMahoro, "compile", mahoro_compile, 1);
|
184
|
+
rb_define_method(cMahoro, "load", mahoro_load, 1);
|
185
|
+
}
|
186
|
+
|
187
|
+
/* arch-tag: mahoro */
|
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/pylink
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
"""
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-filemagic
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Travis Whitton
|
8
|
+
- Jens Wille
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2008-09-18 00:00:00 +02:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: Ruby bindings to the magic(4) library
|
18
|
+
email:
|
19
|
+
- tinymountain@gmail.com
|
20
|
+
- jens.wille@uni-koeln.de
|
21
|
+
executables: []
|
22
|
+
|
23
|
+
extensions:
|
24
|
+
- ext/extconf.rb
|
25
|
+
extra_rdoc_files:
|
26
|
+
- README
|
27
|
+
files:
|
28
|
+
- lib/filemagic/ext.rb
|
29
|
+
- lib/filemagic/version.rb
|
30
|
+
- lib/filemagic.rb
|
31
|
+
- ext/filemagic.c
|
32
|
+
- test/pyfile
|
33
|
+
- test/pyfile-compressed.gz
|
34
|
+
- test/perl
|
35
|
+
- test/leaktest.rb
|
36
|
+
- test/mahoro.c
|
37
|
+
- test/filemagic_test.rb
|
38
|
+
- test/pylink
|
39
|
+
- README
|
40
|
+
- CHANGELOG
|
41
|
+
- TODO
|
42
|
+
- Rakefile
|
43
|
+
- info/filemagic.rd
|
44
|
+
- info/example.rb
|
45
|
+
has_rdoc: true
|
46
|
+
homepage: http://ruby-filemagic.rubyforge.org/
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options:
|
49
|
+
- --line-numbers
|
50
|
+
- --main
|
51
|
+
- README
|
52
|
+
- --all
|
53
|
+
- --inline-source
|
54
|
+
- --title
|
55
|
+
- ruby-filemagic Application documentation
|
56
|
+
- --charset
|
57
|
+
- UTF-8
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: "0"
|
65
|
+
version:
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: "0"
|
71
|
+
version:
|
72
|
+
requirements: []
|
73
|
+
|
74
|
+
rubyforge_project: ruby-filemagic
|
75
|
+
rubygems_version: 1.2.0
|
76
|
+
signing_key:
|
77
|
+
specification_version: 2
|
78
|
+
summary: Ruby bindings to the magic(4) library
|
79
|
+
test_files: []
|
80
|
+
|