magikku 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/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Eric Monti
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.rdoc ADDED
@@ -0,0 +1,18 @@
1
+ = ruby-magic
2
+
3
+ Ruby bindings for libmagic(3)
4
+
5
+ Includes FFI bindings as well as native ruby bindings (the latter is coming soon)..
6
+
7
+ == Synopsis
8
+
9
+ (coming soon)
10
+
11
+ == Installation
12
+
13
+ (sudo)? gem install ruby-magic
14
+
15
+
16
+ == Copyright
17
+
18
+ Copyright (c) 2011 Eric Monti. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,61 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "magikku"
8
+ gem.summary = "Ruby bindings for the libmagic(3) library"
9
+ gem.description = "Ruby bindings to the libmagic(3) library for identifying unknown files and data contents"
10
+ gem.email = "esmonti@gmail.com"
11
+ gem.homepage = "http://github.com/emonti/magikku"
12
+ gem.authors = ["Eric Monti"]
13
+ gem.add_development_dependency "ffi", ">= 0.5.0"
14
+ gem.add_development_dependency "rspec", ">= 1.2.9"
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'spec/rake/spectask'
22
+ Spec::Rake::SpecTask.new(:spec) do |spec|
23
+ spec.libs << 'lib' << 'spec'
24
+ spec.spec_files = FileList['spec/**/*_spec.rb']
25
+ end
26
+
27
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
28
+ spec.libs << 'lib' << 'spec'
29
+ spec.pattern = 'spec/**/*_spec.rb'
30
+ spec.rcov = true
31
+ end
32
+
33
+ require 'rake/extensiontask'
34
+ Rake::ExtensionTask.new("magikku_native")
35
+
36
+ CLEAN.include("doc")
37
+ CLEAN.include("rdoc")
38
+ CLEAN.include("coverage")
39
+ CLEAN.include("tmp")
40
+ CLEAN.include("lib/*.bundle")
41
+ CLEAN.include("lib/*.so")
42
+
43
+ task :spec => [:check_dependencies, :compile]
44
+
45
+ task :default => :spec
46
+
47
+ require 'rake/rdoctask'
48
+ Rake::RDocTask.new do |rdoc|
49
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
50
+
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.title = "magikku #{version}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ rdoc.rdoc_files.include('ext/**/*.c')
56
+ end
57
+
58
+ require 'yard'
59
+ YARD::Rake::YardocTask.new
60
+
61
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,32 @@
1
+ # yara-ruby - Ruby bindings for the yara malware analysis library.
2
+ # Eric Monti
3
+ # Copyright (C) 2011 Trustwave Holdings
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify it
6
+ # under the terms of the GNU General Public License as published by the
7
+ # Free Software Foundation, either version 3 of the License, or (at your
8
+ # option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful, but
11
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12
+ # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
+ # for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License along
16
+ # with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ require 'mkmf'
20
+ require 'rbconfig'
21
+
22
+ extension_name = "magikku_native"
23
+
24
+ dir_config(extension_name)
25
+
26
+ unless have_library("magic") and
27
+ find_header("magic.h", "/usr/local/include")
28
+ raise "You must install the libmagic library"
29
+ end
30
+
31
+ create_makefile(extension_name)
32
+
@@ -0,0 +1,412 @@
1
+ #include "ruby.h"
2
+ #include <magic.h>
3
+ #include <sys/stat.h>
4
+ #include <string.h>
5
+
6
+ VALUE c_magic = Qnil;
7
+ VALUE m_flags = Qnil;
8
+
9
+ VALUE e_MagikkuError = Qnil;
10
+ VALUE e_InitFatal = Qnil;
11
+ VALUE e_DbLoadError = Qnil;
12
+ VALUE e_CompileError = Qnil;
13
+ VALUE e_FlagError = Qnil;
14
+ VALUE e_ClosedError = Qnil;
15
+
16
+
17
+
18
+
19
+ /* Internal function to check whether a handle is already closed */
20
+ magic_t
21
+ _check_closed(VALUE self) {
22
+ magic_t ret = NULL;
23
+ if (rb_iv_get(self, "@closed") != Qtrue)
24
+ Data_Get_Struct(self, void, ret);
25
+ return (magic_t) ret;
26
+ }
27
+
28
+ /* internal MACRO to check for the existence of a file */
29
+ #define _confirm_file_exists(_filename) \
30
+ { struct stat st;\
31
+ if(stat(_filename, &st) < 0) rb_sys_fail(_filename); }
32
+
33
+ #define CLOSED_ERR_MSG "This magic cookie is closed and can no longer be used"
34
+
35
+ /* call-seq: Magikku.path() -> "default_magic_db"
36
+ *
37
+ * @return String Returns the default magic database path.
38
+ */
39
+ VALUE
40
+ rb_magic_s_path(VALUE klass) {
41
+ return rb_str_new2(magic_getpath(NULL, 0));
42
+ }
43
+
44
+ /* call-seq: Magikku.new(params={})
45
+ *
46
+ * Instantiates a new Magikku cookie which we can use to load magic databases,
47
+ * compile new databases, and identify files and string buffers.
48
+ *
49
+ * @param Hash params
50
+ * A hash of optional parameters to pass to the initializer.
51
+ *
52
+ * @option params String :db
53
+ * One or more magic databases to load on initialization. If nothing
54
+ * is specified, the default database will be used.
55
+ *
56
+ * @option params Fixnum :flags
57
+ * Initialization flags to configure libmagic.
58
+ *
59
+ * @see Magikku::Flags and libmagic(3)
60
+ *
61
+ * @raise Magikku::DbLoadError
62
+ * An error is raised if the database cannot be loaded.
63
+ *
64
+ * @raise Magikku::InitFatal
65
+ * An error is raised if an unknown error is encountered initializing
66
+ * the cookie with libmagic.
67
+ */
68
+ VALUE
69
+ rb_magic_initialize(int argc, VALUE *argv, VALUE klass) {
70
+ VALUE params = Qnil;
71
+ VALUE flags_val, db_val;
72
+ magic_t cookie;
73
+ int flags = 0;
74
+ char *magicf = NULL;
75
+ const char *error=NULL;
76
+
77
+ rb_scan_args(argc, argv, "01", &params);
78
+
79
+ if (params != Qnil) {
80
+ Check_Type(params, T_HASH);
81
+
82
+ flags_val=rb_hash_aref(params, ID2SYM(rb_intern("flags")));
83
+ if (flags_val != Qnil) {
84
+ Check_Type(flags_val, T_FIXNUM);
85
+ flags = NUM2INT(flags_val);
86
+ }
87
+
88
+ db_val=rb_hash_aref(params, ID2SYM(rb_intern("db")));
89
+ if (db_val != Qnil) {
90
+ Check_Type(db_val, T_STRING);
91
+ magicf = RSTRING_PTR(db_val);
92
+ }
93
+ }
94
+
95
+ if ((cookie=magic_open(flags))==NULL)
96
+ rb_raise(e_InitFatal, "magic_open(%i) returned a null pointer", flags);
97
+
98
+ if (magic_load(cookie, magicf) != 0) {
99
+ error = magic_error(cookie);
100
+ magic_close(cookie);
101
+ rb_raise(e_DbLoadError, "Error loading db \"%s\": %s", magicf, error);
102
+ }
103
+
104
+ return Data_Wrap_Struct(klass, NULL, NULL, cookie);
105
+ }
106
+
107
+
108
+ /* call-seq: dbload(magicfiles) -> true
109
+ *
110
+ * Used to load one or more magic databases.
111
+ *
112
+ * @param String magicfiles
113
+ * One or more filenames seperated by colons. If nil, the default database
114
+ * is loaded.
115
+ * If uncompiled magic files are specified, they are compiled on the fly
116
+ * but they do not generate new .mgc files as with the compile method.
117
+ * Multiple files be specified by seperating them with colons.
118
+ *
119
+ * @raise DbLoadError if an error occurred loading the database(s)
120
+ *
121
+ * @raise Magikku::CloseError
122
+ * Raises an error if the Magikku object has been closed.
123
+ */
124
+ VALUE
125
+ rb_magic_dbload(VALUE self, VALUE magicf_val) {
126
+ magic_t cookie = _check_closed(self);
127
+ char *magicf = NULL;
128
+
129
+ if(!cookie) rb_raise(e_ClosedError, CLOSED_ERR_MSG);
130
+ if(magicf_val != Qnil){
131
+ Check_Type(magicf_val, T_STRING);
132
+ magicf = RSTRING_PTR(magicf_val);
133
+ }
134
+
135
+ Data_Get_Struct(self, void, cookie);
136
+
137
+ if (magic_load(cookie, magicf) != 0)
138
+ rb_raise(e_DbLoadError, "Error loading db \"%s\": %s", magicf, magic_error(cookie));
139
+
140
+ return Qtrue;
141
+ }
142
+
143
+ /* call-seq: close() -> nil
144
+ *
145
+ * Close the libmagic data scanner handle when you are finished with it
146
+ *
147
+ * Note that magic handles are never closed automatically, even when
148
+ * garbage collection occurs.
149
+ */
150
+ VALUE
151
+ rb_magic_close(VALUE self) {
152
+ magic_t cookie = _check_closed(self);
153
+
154
+ if(cookie) magic_close(cookie);
155
+ rb_iv_set(self, "@closed", Qtrue);
156
+
157
+ return Qnil;
158
+ }
159
+
160
+ /* call-seq: closed? -> true|false
161
+ *
162
+ * Indicates whether the magic cookie has been closed
163
+ *
164
+ * @return true,false
165
+ */
166
+ VALUE
167
+ rb_magic_is_closed(VALUE self) {
168
+ VALUE ret = rb_iv_get(self, "@closed");
169
+ if (ret == Qnil) ret = Qfalse;
170
+ return ret;
171
+ }
172
+
173
+ /* call-seq: file(filename) -> String
174
+ *
175
+ * Identifies file contents using the magicfile database.
176
+ *
177
+ * @param String filename
178
+ * The path to the file to analyze
179
+ *
180
+ * @return String
181
+ * A textual description of the contents of the file
182
+ *
183
+ * @raise Magikku::CloseError
184
+ * Raises an error if the Magikku object has been closed.
185
+ */
186
+ VALUE
187
+ rb_magic_file(VALUE self, VALUE filename) {
188
+ magic_t cookie = _check_closed(self);
189
+ if (cookie) {
190
+ char * fname;
191
+ struct stat st;
192
+
193
+ Check_Type(filename, T_STRING);
194
+ fname = RSTRING_PTR(filename);
195
+
196
+ if(stat(fname, &st) < 0)
197
+ rb_sys_fail(fname);
198
+
199
+ return rb_str_new2(magic_file(cookie, fname));
200
+
201
+ } else {
202
+ rb_raise(e_ClosedError, CLOSED_ERR_MSG);
203
+ }
204
+
205
+ }
206
+
207
+ /* call-seq: string(buf) -> String
208
+ *
209
+ * Identifies string contents using the magicfile database.
210
+ *
211
+ * @param String buf
212
+ * The string to analyze.
213
+ *
214
+ * @return String
215
+ * A textual description of the contents of the string
216
+ *
217
+ * @raise Magikku::CloseError
218
+ * Raises an error if the Magikku object has been closed.
219
+ */
220
+ VALUE rb_magic_string(VALUE self, VALUE string) {
221
+ const char *ret;
222
+ magic_t cookie = _check_closed(self);
223
+ if (!cookie) rb_raise(e_ClosedError, CLOSED_ERR_MSG);
224
+ Check_Type(string, T_STRING);
225
+
226
+ ret=magic_buffer(cookie, RSTRING_PTR(string), RSTRING_LEN(string));
227
+ return rb_str_new2(ret);
228
+ }
229
+
230
+ /* call-seq: compile(filename=nil)
231
+ *
232
+ * Can be used to compile magic files. This does not load files, however. You must
233
+ * use dbload for that.
234
+ *
235
+ * Note: Errors and warnings may be displayed on stderr.
236
+ *
237
+ * @param String,nil filename
238
+ * A colon seperated list of filenames or a single filename.
239
+ * The compiled files created are generated in the current directory using
240
+ * the basename(1) of each file argument with ".mgc" appended to it.
241
+ * Directory names can be compiled, in which case the contents of the
242
+ * directory will be compiled together as a single .mgc file.
243
+ * nil compiles the default database.
244
+ *
245
+ * @return true if everything went well.
246
+ *
247
+ * @raise CompileError if an error occurred.
248
+ */
249
+ VALUE rb_magic_compile(VALUE self, VALUE magicf) {
250
+ char *_magicf;
251
+ magic_t cookie = _check_closed(self);
252
+
253
+ if (!cookie) rb_raise(e_ClosedError, CLOSED_ERR_MSG);
254
+ if (magicf != Qnil) Check_Type(magicf, T_STRING);
255
+
256
+ _magicf = RSTRING_PTR(magicf);
257
+
258
+ if (magic_compile(cookie, _magicf) == 0) return Qtrue;
259
+ else rb_raise(e_CompileError,
260
+ "Error compiling \"%s\": %s", _magicf, magic_error(cookie));
261
+ }
262
+
263
+ /* call-seq: magic.check_syntax("some_magic_db") -> (true|false)
264
+ *
265
+ * Can be used to check the validity of magic files before compiling them.
266
+ * This is basically a dry-run that can be used before compiling magicfile
267
+ * databases.
268
+ *
269
+ * Note: Errors and warnings may be displayed on stderr.
270
+ *
271
+ * @param String,nil filename
272
+ * A colon seperated list of filenames or a single file. nil checks the
273
+ * default database.
274
+ *
275
+ * @return true,false Indicates whether the check was successful.
276
+ */
277
+ VALUE rb_magic_check_syntax(VALUE self, VALUE rb_magicf) {
278
+ magic_t cookie = _check_closed(self);
279
+ char * magicf = NULL;
280
+
281
+ if (!cookie) rb_raise(e_ClosedError, CLOSED_ERR_MSG);
282
+ if (rb_magicf != Qnil) {
283
+ Check_Type(rb_magicf, T_STRING);
284
+ magicf = RSTRING_PTR(rb_magicf);
285
+ }
286
+
287
+ if (magic_check(cookie, magicf) == 0) return Qtrue;
288
+ else return Qfalse;
289
+ }
290
+
291
+ /* call-seq: magic.flags = (Magikku::Flags::MIME | Magikku::Flags::DEBUG)
292
+ *
293
+ * Sets libmagic flags on the object. See Magikku::Flags
294
+ *
295
+ * @raise Magikku::CloseError
296
+ * Raises an error if the Magikku object has been closed.
297
+ */
298
+ VALUE rb_magic_set_flags(VALUE self, VALUE flags) {
299
+ magic_t cookie = _check_closed(self);
300
+
301
+ Check_Type(flags, T_FIXNUM);
302
+
303
+ if(magic_setflags(cookie, NUM2INT(flags)) < 0)
304
+ rb_raise(e_FlagError, magic_error(cookie));
305
+
306
+ return flags;
307
+ }
308
+
309
+ void Init_magikku_native() {
310
+ /* The Magikku class is both our interface to libmagic functionality
311
+ as well as the top-level namespace */
312
+ c_magic = rb_define_class("Magikku", rb_cObject);
313
+ rb_define_singleton_method(c_magic, "path", rb_magic_s_path, 0);
314
+ // rb_define_singleton_method(c_magic, "compile", rb_magic_s_compile, 1);
315
+ // rb_define_singleton_method(c_magic, "check_syntax", rb_magic_s_check_syntax, 1);
316
+
317
+ rb_define_singleton_method(c_magic, "new", rb_magic_initialize, -1);
318
+
319
+ rb_define_method(c_magic, "close", rb_magic_close, 0);
320
+ rb_define_method(c_magic, "closed?", rb_magic_is_closed, 0);
321
+ rb_define_method(c_magic, "compile", rb_magic_compile, 1);
322
+ rb_define_method(c_magic, "check_syntax", rb_magic_check_syntax, 1);
323
+ rb_define_method(c_magic, "file", rb_magic_file, 1);
324
+ rb_define_method(c_magic, "string", rb_magic_string, 1);
325
+ rb_define_method(c_magic, "flags=", rb_magic_set_flags, 1);
326
+ rb_define_method(c_magic, "dbload", rb_magic_dbload, 1);
327
+
328
+ /* Defines various flags that can be passed when creating a magic scanning
329
+ * object using Magikku.new with the :flags parameter or after instantiation
330
+ * using Magikku.flags= .
331
+ *
332
+ * Available flags are as follows:
333
+ *
334
+ * NONE No flags
335
+ * DEBUG Turn on debugging
336
+ * SYMLINK Follow symlinks
337
+ * COMPRESS Check inside compressed files
338
+ * DEVICES Look at the contents of devices
339
+ * MIME_TYPE Return the MIME type
340
+ * CONTINUE Return all matches
341
+ * CHECK Print warnings to stderr
342
+ * PRESERVE_ATIME Restore access time on exit
343
+ * RAW Don't translate unprintable chars
344
+ * ERROR Handle ENOENT etc as real errors
345
+ * MIME_ENCODING Return the MIME encoding
346
+ * MIME Alias for (MIME_TYPE|MIME_ENCODING)
347
+ * APPLE Return the Apple creator and type
348
+ * NO_CHECK_COMPRESS Don't check for compressed files
349
+ * NO_CHECK_TAR Don't check for tar files
350
+ * NO_CHECK_SOFT Don't check magic entries
351
+ * NO_CHECK_APPTYPE Don't check application type
352
+ * NO_CHECK_ELF Don't check for elf details
353
+ * NO_CHECK_TEXT Don't check for text files
354
+ * NO_CHECK_CDF Don't check for cdf files
355
+ * NO_CHECK_TOKENS Don't check tokens
356
+ * NO_CHECK_ENCODING Don't check text encodings
357
+ * NO_CHECK_ASCII Alias for NO_CHECK_TEXT
358
+ *
359
+ * @see libmagic(3)
360
+ *
361
+ */
362
+ m_flags = rb_define_module_under(c_magic, "Flags");
363
+ rb_define_const(m_flags, "NONE", INT2FIX(MAGIC_NONE));
364
+ rb_define_const(m_flags, "DEBUG", INT2FIX(MAGIC_DEBUG));
365
+ rb_define_const(m_flags, "SYMLINK", INT2FIX(MAGIC_SYMLINK));
366
+ rb_define_const(m_flags, "COMPRESS", INT2FIX(MAGIC_COMPRESS));
367
+ rb_define_const(m_flags, "DEVICES", INT2FIX(MAGIC_DEVICES));
368
+ rb_define_const(m_flags, "MIME_TYPE", INT2FIX(MAGIC_MIME_TYPE));
369
+ rb_define_const(m_flags, "CONTINUE", INT2FIX(MAGIC_CONTINUE));
370
+ rb_define_const(m_flags, "CHECK", INT2FIX(MAGIC_CHECK));
371
+ rb_define_const(m_flags, "PRESERVE_ATIME", INT2FIX(MAGIC_PRESERVE_ATIME));
372
+ rb_define_const(m_flags, "RAW", INT2FIX(MAGIC_RAW));
373
+ rb_define_const(m_flags, "ERROR", INT2FIX(MAGIC_ERROR));
374
+ rb_define_const(m_flags, "MIME_ENCODING", INT2FIX(MAGIC_MIME_ENCODING));
375
+ rb_define_const(m_flags, "MIME", INT2FIX(MAGIC_MIME));
376
+ rb_define_const(m_flags, "APPLE", INT2FIX(MAGIC_APPLE));
377
+ rb_define_const(m_flags, "NO_CHECK_COMPRESS", INT2FIX(MAGIC_NO_CHECK_COMPRESS));
378
+ rb_define_const(m_flags, "NO_CHECK_TAR", INT2FIX(MAGIC_NO_CHECK_TAR));
379
+ rb_define_const(m_flags, "NO_CHECK_SOFT", INT2FIX(MAGIC_NO_CHECK_SOFT));
380
+ rb_define_const(m_flags, "NO_CHECK_APPTYPE", INT2FIX(MAGIC_NO_CHECK_APPTYPE));
381
+ rb_define_const(m_flags, "NO_CHECK_ELF", INT2FIX(MAGIC_NO_CHECK_ELF));
382
+ rb_define_const(m_flags, "NO_CHECK_TEXT", INT2FIX(MAGIC_NO_CHECK_TEXT));
383
+ rb_define_const(m_flags, "NO_CHECK_CDF", INT2FIX(MAGIC_NO_CHECK_CDF));
384
+ rb_define_const(m_flags, "NO_CHECK_TOKENS", INT2FIX(MAGIC_NO_CHECK_TOKENS));
385
+ rb_define_const(m_flags, "NO_CHECK_ENCODING", INT2FIX(MAGIC_NO_CHECK_ENCODING));
386
+ rb_define_const(m_flags, "NO_CHECK_ASCII", INT2FIX(MAGIC_NO_CHECK_ASCII));
387
+
388
+ /* define our exception classes... */
389
+
390
+ /* A base class for other Magikku error types */
391
+ e_MagikkuError = rb_define_class_under(c_magic, "MagikkuError", rb_eStandardError);
392
+
393
+ /* InitFatal is raised for unexpected errors initializing Magikku */
394
+ e_InitFatal = rb_define_class_under(c_magic, "InitFatal", e_MagikkuError);
395
+
396
+ /* DbLoadError is raised when an error occurs loading a magic database */
397
+ e_DbLoadError = rb_define_class_under(c_magic, "DbLoadError", e_MagikkuError);
398
+
399
+ /* CompileError is raised when an error occurs compiling a magic database */
400
+ e_CompileError = rb_define_class_under(c_magic, "CompileError", e_MagikkuError);
401
+
402
+ /* FlagError is raised when an error occurs compiling setting flags
403
+ *
404
+ * This is only known to happen on systems that don't support utime(2), or
405
+ * utimes(2) when Magikku::Flag::PRESERVE_ATIME is set
406
+ */
407
+ e_FlagError = rb_define_class_under(c_magic, "FlagError", e_MagikkuError);
408
+
409
+ /* ClosedError is raised if an operation is called on a closed Magikku object */
410
+ e_ClosedError = rb_define_class_under(c_magic, "ClosedError", e_MagikkuError);
411
+
412
+ }
@@ -0,0 +1,46 @@
1
+ require 'ffi'
2
+
3
+ module FFI
4
+ module Libmagic
5
+ extend FFI::Library
6
+ ffi_lib 'magic'
7
+
8
+ typedef :pointer, :magic_t
9
+
10
+ # magic_t magic_open(int flags);
11
+ attach_function :magic_open, [:int], :magic_t
12
+
13
+ # void magic_close(magic_t cookie);
14
+ attach_function :magic_close, [:magic_t], :void
15
+
16
+ # const char * magic_error(magic_t cookie);
17
+ attach_function :magic_error, [:magic_t], :string
18
+
19
+ # int magic_errno(magic_t cookie);
20
+ attach_function :magic_errno, [:magic_t], :int
21
+
22
+ # const char * magic_file(magic_t cookie, const char *filename);
23
+ attach_function :magic_file, [:magic_t, :string], :string
24
+
25
+ # const char * magic_buffer(magic_t cookie, const void *buffer, size_t length);
26
+ attach_function :magic_buffer, [:magic_t, :pointer, :size_t], :string
27
+
28
+ # int magic_setflags(magic_t cookie, int flags);
29
+ attach_function :magic_setflags, [:magic_t, :int], :int
30
+
31
+ # int magic_check(magic_t cookie, const char *filename);
32
+ attach_function :magic_check, [:magic_t, :string], :int
33
+
34
+ # int magic_compile(magic_t cookie, const char *filename);
35
+ attach_function :magic_compile, [:magic_t, :string], :int
36
+
37
+ # int magic_load(magic_t cookie, const char *filename);
38
+ attach_function :magic_load, [:magic_t, :string], :int
39
+
40
+ # NOTE magic_getpath not doc'd in libmagic(3),
41
+ # not available in earlier versions?
42
+ #
43
+ # const char * int magic_getpath(const char *magicfile, int action)
44
+ attach_function :magic_getpath, [:string, :int], :string
45
+ end
46
+ end
@@ -0,0 +1,82 @@
1
+
2
+ module MagikkuHelpers
3
+ # A convenience method for checking syntax of magicdb files.
4
+ #
5
+ # Note: syntax errors and warnings may be displayed on stderr.
6
+ #
7
+ # @param String fname
8
+ # Filename or directory to compile
9
+ #
10
+ # @param Hash params
11
+ # A hash of parameters to Magikku.new()
12
+ #
13
+ # @return true,false
14
+ def check_syntax(fname, params={})
15
+ m=new(params)
16
+ begin
17
+ return m.check_syntax(fname)
18
+ ensure
19
+ m.close()
20
+ end
21
+ end
22
+
23
+ # A convenience method for compiling magicdb files.
24
+ #
25
+ # @param String fname
26
+ # Filename or directory to compile
27
+ #
28
+ # @param Hash params
29
+ # A hash of parameters to Magikku.new()
30
+ #
31
+ # @return true
32
+ #
33
+ # @raise Magikku::CompileError if an error occurs
34
+ def compile(fname, params={})
35
+ m=new(params)
36
+ begin
37
+ return m.compile(fname)
38
+ ensure
39
+ m.close()
40
+ end
41
+ end
42
+
43
+ # A convenience method for identifying file contents
44
+ #
45
+ # @param String fname
46
+ # Filename to identify
47
+ #
48
+ # @param Hash params
49
+ # A hash of parameters to Magikku.new()
50
+ #
51
+ # @return String
52
+ # Identification of the file contents.
53
+ def file(fname, params={})
54
+ m=new(params)
55
+ begin
56
+ return m.file(fname)
57
+ ensure
58
+ m.close()
59
+ end
60
+ end
61
+
62
+ # A convenience method for identifying string contents
63
+ #
64
+ # @param String buf
65
+ # String contents to identify
66
+ #
67
+ # @param Hash params
68
+ # A hash of parameters to Magikku.new()
69
+ #
70
+ # @return String
71
+ # Identification of the string.
72
+ def string(buf, params={})
73
+ m=new(params)
74
+ begin
75
+ return m.string(buf)
76
+ ensure
77
+ m.close()
78
+ end
79
+ end
80
+ end
81
+
82
+
data/lib/magikku.rb ADDED
@@ -0,0 +1,12 @@
1
+
2
+ require 'magikku/convenience'
3
+
4
+ #begin
5
+ require 'magikku_native'
6
+ Magikku.class_eval{ extend(MagikkuHelpers) }
7
+ #rescue LoadError
8
+ # require 'magikku_ffi'
9
+ # Magikku = MagikkuFFI
10
+ #end
11
+
12
+