libmagic_rb 0.1.1.pre.alpha → 0.1.2.pre.gamma

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9742d29b9e36ec2a6de0079d215965133e97a7f9f03fc9d568b678c229e1c104
4
- data.tar.gz: ebc7eccd373d353a3954946d0d88ef92956d478d36fbc4509c7c3cc029fa5de7
3
+ metadata.gz: 116d3dc132643a74f2a887128844a9faa5a4b0a53b7aded5e70bd296087ad005
4
+ data.tar.gz: 77f551eddaae7a4d1e70840608ec008cc509569d5c9153d0e07f7d710fc371e7
5
5
  SHA512:
6
- metadata.gz: ea9103f6c7eb96a772e1d712f6a09547c753dee9561c3196de841d998c9200d1104b8fb03b702d8c025c438b9ad728658ff405ffc95e546afa7d834809bb75a7
7
- data.tar.gz: 3d0d0bf0308e8472fd77019c3deb00a55869f5a2576b230682690d291023eff69700203b7ec13a3b4b0f1323824f2c61b2bfe281b0dca8ef33dc48c80c374fa5
6
+ metadata.gz: 804a95966aeca5e305ff5b6d18a733528dcbf179617cefb461bd779c0dbbb8aa044d6edeca9a55b2b04b62c8c6b8c69b82f8d0a4c7663eba43e6798b8ab51a31
7
+ data.tar.gz: fefe9f019f2decd1e85f7836eacbac01bc6c5e9f22beb22d5e271b903eed83d7b6e25d942e3460be4a2f92d9312faa4eaac477775b6c75c36e23d68035634813
data/README.md CHANGED
@@ -1,35 +1,79 @@
1
- # LibmagicRb
1
+ # LibmagicRb [![Gem Version](https://badge.fury.io/rb/libmagic_rb.svg)](https://rubygems.org/gems/libmagic_rb) ![Workflow Status](https://github.com/cybergizer-hq/libmagicrb/workflows/LibmagicRb%20Test/badge.svg)
2
+
2
3
  Adds ability to check mime-type of a file using the libmagic ([magic(4)](https://man7.org/linux/man-pages/man4/magic.4.html)).
3
4
  It uses native extensions and it's quite performant.
4
5
 
5
6
  ## Pre-Installation
6
- On Linux, you need to install libmagic.
7
+ On Linux, you need to install libmagic. The version we recommend is at least 5.36.
8
+ But if you have an older version of libmagic, it will compile and work flawlessly but with a few caveats:
9
+
10
+ + Many constants (modes and params) will be not defined
11
+ + LibmagicRb::MAGIC_VERSION constant will be set to 0.
12
+ + Few methods will not work.
13
+ some methods that can return a String or Integer will return nil (like setparam and getparam).
14
+
15
+ [ Do note that the minimum tested version is 5.11, older than that may fail to compile the gem ]
7
16
 
8
- ##### Arch
17
+ You also need Ruby > 1.9.0 in order to run this gem.
18
+
19
+ With that info in mind, let's continue to the installation part for your Linux distributions...
20
+
21
+ #### Arch / Manjaro / Archlabs / Garuda Linux / Hefftor Linux & other Arch Based Linux
9
22
 
10
23
  ```
11
- # pacman -S file gcc make
24
+ # pacman -S ruby file gcc make --needed
12
25
  ```
13
26
 
14
- #### Debian / Ubuntu / Linux Mint / Kali / ParrotOS / RaspberryPi OS
27
+ #### Debian / Ubuntu / Linux Mint / Deepin / Pop!_OS / RaspberryPi OS & other Debian Based Linux
15
28
 
16
29
  ```
17
- # apt install libmagic-dev ruby-dev gcc make
30
+ # apt install ruby libmagic-dev ruby-dev gcc make
18
31
  ```
19
32
 
20
- #### Fedora
33
+ #### Fedora / Amazon Linux / CentOS & Other RedHat Based Linux
21
34
 
22
35
  ```
23
- # yum install file-devel ruby-devel gcc make
36
+ # yum install ruby file-devel ruby-devel gcc make
24
37
  ```
25
38
 
26
39
  #### OpenSUSE
27
40
 
28
41
  ```
29
- zypper in ruby ruby-devel file-devel gcc make
42
+ # zypper in ruby ruby-devel file-devel gcc make
43
+ ```
44
+
45
+ #### Gentoo
46
+
47
+ There are already make, and magic.h available for Gentoo. You just need Ruby:
48
+
49
+ ```
50
+ # emerge --ask dev-lang/ruby
51
+ ```
52
+
53
+ #### DragonflyBSD / FreeBSD
54
+
55
+ Versions upto 0.1.2 is tested on DragonflyBSD (Version 6.0-SYNTH).
56
+
57
+ ```
58
+ # pkg install ruby devel/ruby-gems gcc gmake
59
+ ```
60
+
61
+ #### MacOS
62
+
63
+ You can install libmagic with homebrew:
64
+
65
+ ```
66
+ $ brew install libmagic
67
+
68
+ # if the link is already created is going to fail, don't worry about that
69
+ $ brew link libmagic
30
70
  ```
31
71
 
32
- Mac is currently not supported but may support in the future.
72
+ [ Source: [ eparreno/gist:1845561 ](https://gist.github.com/eparreno/1845561) ]
73
+
74
+ #### Windows
75
+
76
+ Windows is currently not tested, hence the support is unknown.
33
77
 
34
78
  ## Installation
35
79
 
@@ -51,6 +95,9 @@ Or install it yourself as:
51
95
  $ gem install libmagic_rb
52
96
  ```
53
97
 
98
+ We recommend getting the gem only from Rubygems.org. Do not download this repo as zip, compile to install the gem.
99
+ A rubygem version is released after various tests. Any branch here including Master branch can be unstable can even segfault your app. You've been warned!
100
+
54
101
  ## Usage
55
102
  The target of this gem is to add mime-type checking easily.
56
103
 
@@ -162,18 +209,19 @@ cookie.setparam(LibmagicRb::MAGIC_PARAM_REGEX_MAX, 2 ** 14) # => 16384; but can
162
209
 
163
210
  #### Notes:
164
211
 
165
- + To get the parameters, you can refer to the [man page](https://man7.org/linux/man-pages/man3/magic_getflags.3.html).
166
- + Cookie setparam returns the value after getting the param as well. So you don't need to confirm by calling getparam() again.
212
+ + To get the parameters, you can run `LibmagicRb.lsparams()` for description, please refer to the [man page](https://man7.org/linux/man-pages/man3/magic_getflags.3.html).
213
+ + `cookie.setparam()` returns the value after getting the param as well. So you don't need to confirm by calling getparam() again.
167
214
  + The maximum size depends on the parameter. But the value that can be passed should not be more than 2 ** 32.
215
+ + On older versions of libmagic, where the function isn't available, both getparam() and setparam() will perform no operations, and return nil!
168
216
 
169
217
  ## Errors
170
218
  The following errors are implemented and raised on appropriate situation:
171
219
 
172
- 1. LibmagicRb::FileNotFound: When the file is not found.
173
- 2. LibmagicRb::FileUnreadable: When the file is unreadable.
174
- 3. LibmagicRb::InvalidDBError: When the database given is invalid.
175
- 4. LibmagicRb::IsDirError: When the database path is a directory.
176
- 5. LibmagicRb::FileClosedError: When the file is already closed (closed?()) but you are trying to access the cookie.
220
+ 1. `LibmagicRb::FileNotFound`: When the file is not found.
221
+ 2. `LibmagicRb::FileUnreadable`: When the file is unreadable.
222
+ 3. `LibmagicRb::InvalidDBError`: When the database given is invalid.
223
+ 4. `LibmagicRb::IsDirError`: When the database path is a directory.
224
+ 5. `LibmagicRb::FileClosedError`: When the file is already closed (closed?()) but you are trying to access the cookie.
177
225
 
178
226
  ## Development
179
227
 
data/ext/libmagic/func.h CHANGED
@@ -1,3 +1,15 @@
1
+ /*
2
+ Closes a magic cookie. For example:
3
+
4
+ > cookie = LibmagicRb.new(file: '/usr/share/dict/words')
5
+ # => #<LibmagicRb:0x00005581019fa7e0 @closed=false, @db=nil, @file="/usr/share/dict/words", @mode=1106>
6
+
7
+ > cookie.close
8
+ # => #<LibmagicRb:0x00005581019fa7e0 @closed=true, @db=nil, @file="/usr/share/dict/words", @mode=1106>
9
+
10
+ Returns self.
11
+ */
12
+
1
13
  VALUE _closeGlobal_(volatile VALUE self) {
2
14
  RB_UNWRAP(cookie) ;
3
15
 
@@ -7,6 +19,23 @@ VALUE _closeGlobal_(volatile VALUE self) {
7
19
  return self ;
8
20
  }
9
21
 
22
+ /*
23
+ Changes the database path. For example:
24
+ > cookie = LibmagicRb.new(file: '/usr/share/dict/words')
25
+ # => #<LibmagicRb:0x00005581019181b0 @closed=false, @db=nil, @file="/usr/share/dict/words", @mode=1106>
26
+
27
+ > cookie.db = '/usr/share/file/misc/magic.mgc'
28
+ # => "/usr/share/file/misc/magic.mgc"
29
+
30
+ > cookie.check
31
+ # => "text/plain; charset=utf-8"
32
+
33
+ > cookie.close
34
+ # => #<LibmagicRb:0x00005581019181b0 @closed=true, @db="/usr/share/file/misc/magic.mgc", @file="/usr/share/dict/words", @mode=1106>
35
+
36
+ Returns self.
37
+ */
38
+
10
39
  VALUE _loadGlobal_(volatile VALUE self, volatile VALUE dbPath) {
11
40
  char *databasePath = NULL ;
12
41
 
@@ -27,6 +56,20 @@ VALUE _loadGlobal_(volatile VALUE self, volatile VALUE dbPath) {
27
56
  return self ;
28
57
  }
29
58
 
59
+ /*
60
+ Check a file with the magic database. For example:
61
+ > cookie = LibmagicRb.new(file: '/usr/share/dict/words')
62
+ # => #<LibmagicRb:0x00005581019181b0 @closed=false, @db=nil, @file="/usr/share/dict/words", @mode=1106>
63
+
64
+ > cookie.check
65
+ # => "text/plain; charset=utf-8"
66
+
67
+ > cookie.close
68
+ # => #<LibmagicRb:0x00005581019181b0 @closed=true, @db="/usr/share/file/misc/magic.mgc", @file="/usr/share/dict/words", @mode=1106>
69
+
70
+ Returns String or nil.
71
+ */
72
+
30
73
  VALUE _checkGlobal_(volatile VALUE self) {
31
74
  RB_UNWRAP(cookie) ;
32
75
 
@@ -51,51 +94,188 @@ VALUE _checkGlobal_(volatile VALUE self) {
51
94
  return mt ? rb_str_new_cstr(mt) : Qnil ;
52
95
  }
53
96
 
97
+ /*
98
+ Get parameters for a cookie. For example:
99
+ cookie = LibmagicRb.new(file: '/usr/share/dict/words')
100
+ # => #<LibmagicRb:0x00005581018f35e0 @closed=false, @db=nil, @file="/usr/share/dict/words", @mode=1106>
101
+
102
+ > cookie.getparam(LibmagicRb::MAGIC_PARAM_NAME_MAX)
103
+ # => 50
104
+
105
+ > cookie.close
106
+ # => #<LibmagicRb:0x00005581018f35e0 @closed=true, @db=nil, @file="/usr/share/dict/words", @mode=1106>
107
+ */
108
+
54
109
  VALUE _getParamGlobal_(volatile VALUE self, volatile VALUE param) {
55
- RB_UNWRAP(cookie) ;
110
+ #if MAGIC_VERSION > 525
111
+ RB_UNWRAP(cookie) ;
56
112
 
57
- unsigned int _param = NUM2UINT(param) ;
58
- unsigned long value ;
113
+ unsigned int _param = NUM2UINT(param) ;
114
+ unsigned long value ;
59
115
 
60
- int status = magic_getparam(*cookie, _param, &value) ;
61
- if (status) return Qnil ;
62
- return ULONG2NUM(value) ;
116
+ int status = magic_getparam(*cookie, _param, &value) ;
117
+ if (status) return Qnil ;
118
+ return ULONG2NUM(value) ;
119
+ #else
120
+ return Qnil ;
121
+ #endif
63
122
  }
64
123
 
124
+ /*
125
+ Sets parameter for a cookie. For example:
126
+
127
+ > cookie = LibmagicRb.new(file: '/usr/share/dict/words')
128
+ # => #<LibmagicRb:0x00005581019f9840 @closed=false, @db=nil, @file="/usr/share/dict/words", @mode=1106>
129
+
130
+ > cookie.getparam(LibmagicRb::MAGIC_PARAM_NAME_MAX)
131
+ => 50
132
+
133
+ > cookie.setparam(LibmagicRb::MAGIC_PARAM_NAME_MAX, 101)
134
+ # => 101
135
+
136
+ > cookie.getparam(LibmagicRb::MAGIC_PARAM_NAME_MAX)
137
+ # => 101
138
+
139
+ > cookie.close
140
+ # => #<LibmagicRb:0x00005581019f9840 @closed=true, @db=nil, @file="/usr/share/dict/words", @mode=1106>
141
+
142
+ Returns Integer or nil on failure.
143
+ */
144
+
65
145
  VALUE _setParamGlobal_(volatile VALUE self, volatile VALUE param, volatile VALUE paramVal) {
66
- unsigned int _param = NUM2UINT(param) ;
67
- unsigned long _paramVal = NUM2ULONG(paramVal) ;
146
+ #if MAGIC_VERSION > 525
147
+ unsigned int _param = NUM2UINT(param) ;
148
+ unsigned long _paramVal = NUM2ULONG(paramVal) ;
68
149
 
69
- RB_UNWRAP(cookie) ;
150
+ RB_UNWRAP(cookie) ;
70
151
 
71
- unsigned long value ;
72
- magic_setparam(*cookie, _param, &_paramVal) ;
152
+ unsigned long value ;
153
+ magic_setparam(*cookie, _param, &_paramVal) ;
73
154
 
74
- int status = magic_getparam(*cookie, _param, &value) ;
155
+ int status = magic_getparam(*cookie, _param, &value) ;
156
+ if (status) return Qnil ;
75
157
 
76
- if (status) return Qnil ;
77
- return ULONG2NUM((int)value) ;
158
+ return ULONG2NUM((int)value) ;
159
+ #else
160
+ return Qnil ;
161
+ #endif
78
162
  }
79
163
 
164
+ /*
165
+ Returns a textual description of the contents of the buffer argument with length bytes size.
166
+
167
+ For example:
168
+
169
+ > cookie = LibmagicRb.new(file: '.')
170
+ # => #<LibmagicRb:0x00005582de0d1bf8 @closed=false, @db=nil, @file=".", @mode=1106>
171
+
172
+ > cookie.magic_buffer("%PDF-1.3\r\n")
173
+ # => "application/pdf; charset=us-ascii"
174
+
175
+ > cookie.close
176
+ # => #<LibmagicRb:0x00005582de0d1bf8 @closed=true, @db=nil, @file=".", @mode=1106>
177
+
178
+ Note that it automatically loads the database.
179
+
180
+ Returns either String or nil.
181
+ */
182
+
80
183
  VALUE _bufferGlobal_(volatile VALUE self, volatile VALUE string) {
81
184
  RB_UNWRAP(cookie) ;
82
185
 
186
+ VALUE db = rb_iv_get(self, "@db") ;
187
+
188
+ char *database = NULL ;
189
+ if(RB_TYPE_P(db, T_STRING)) {
190
+ database = StringValuePtr(db) ;
191
+ }
192
+
193
+ if(database) magic_validate_db(*cookie, database) ;
194
+ magic_load(*cookie, database) ;
195
+
83
196
  char *buffer = StringValuePtr(string) ;
84
- const char *buf = magic_buffer(*cookie, buffer, sizeof(buffer)) ;
197
+ const char *buf = magic_buffer(*cookie, buffer, strlen(buffer)) ;
85
198
 
86
- return rb_str_new_cstr(buf) ;
199
+ return buf ? rb_str_new_cstr(buf) : Qnil ;
87
200
  }
88
201
 
202
+ /*
203
+ Dumps all magic entries in a human
204
+ readable format, dumping first the entries that are matched against
205
+ binary files and then the ones that match text files.
206
+
207
+ For example:
208
+
209
+
210
+ > cookie = LibmagicRb.new(file: '.')
211
+ # => #<LibmagicRb:0x000055cf280a9b30 @closed=false, @db=nil, @file=".", @mode=1106>
212
+
213
+ > cookie.magic_list
214
+ Set 0:
215
+ Binary patterns:
216
+ Strength = 500@47: Biosig/Brainvision Marker file [biosig/brainvision]
217
+ Strength = 490@122: Biosig/TMSiLOG [biosig/tmsilog]
218
+ Strength = 461@127: Biosig/SYNERGY [biosig/synergy]
219
+ Strength = 460@46: Biosig/Brainvision V-Amp file []
220
+ Strength = 410@45: Biosig/Brainvision data file []
221
+ Strength = 380@6: OpenSSH private key []
222
+ Strength = 370@1266: Novell message librarian data []
223
+ .
224
+ .
225
+ .
226
+ # => 0
227
+
228
+ > cookie.close
229
+ => #<LibmagicRb:0x000055cf280a9b30 @closed=true, @db=nil, @file=".", @mode=1106>
230
+ */
231
+
89
232
  VALUE _listGlobal_(volatile VALUE self) {
90
233
  RB_UNWRAP(cookie) ;
91
234
 
92
235
  VALUE db = rb_iv_get(self, "@db") ;
93
- char *database = StringValuePtr(db) ;
94
236
 
237
+ char *database = NULL ;
238
+ if (RB_TYPE_P(db, T_STRING)) {
239
+ database = StringValuePtr(db) ;
240
+ }
241
+
242
+ if(database) magic_validate_db(*cookie, database) ;
95
243
  int status = magic_list(*cookie, database) ;
244
+
96
245
  return INT2FIX(status) ;
97
246
  }
98
247
 
248
+ /*
249
+ Set flags/modes for a cookie (not to be confused with params).
250
+ It's same setting mode through the setter cookie.mode = mode.
251
+
252
+ For example:
253
+
254
+ > cookie = LibmagicRb.new(file: '.')
255
+ # => #<LibmagicRb:0x00005583732e1070 @closed=false, @db=nil, @file=".", @mode=1106>
256
+
257
+ > cookie.check
258
+ # => "inode/directory; charset=binary"
259
+
260
+ > cookie.setflags(LibmagicRb::MAGIC_RAW)
261
+ # => 256
262
+
263
+ > cookie.check
264
+ # => "directory"
265
+
266
+ #### Similarly you can also do this ####
267
+
268
+ > cookie.mode = LibmagicRb::MAGIC_MIME
269
+ # => 1040
270
+
271
+ > cookie.check
272
+ # => "inode/directory; charset=binary"
273
+
274
+ #### Close the cookie when done ####
275
+ > cookie.close
276
+ # => #<LibmagicRb:0x00005583732e1070 @closed=true, @db=nil, @file=".", @mode=256>
277
+ */
278
+
99
279
  VALUE _setflagsGlobal_(volatile VALUE self, volatile VALUE flags) {
100
280
  unsigned int flag = NUM2UINT(flags) ;
101
281
 
data/ext/libmagic/magic.c CHANGED
@@ -1,6 +1,7 @@
1
1
  #include <magic.h>
2
2
  #include <stdio.h>
3
3
  #include <unistd.h>
4
+ #include <sys/stat.h>
4
5
  #include "ruby.h"
5
6
 
6
7
  /*
@@ -10,6 +11,10 @@
10
11
  #include "params.h"
11
12
  #include "definitions.h"
12
13
 
14
+ #ifndef MAGIC_VERSION
15
+ #define MAGIC_VERSION 0
16
+ #endif
17
+
13
18
  /*
14
19
  * Errors
15
20
  */
@@ -39,13 +44,30 @@ static rb_data_type_t fileType = {
39
44
  },
40
45
 
41
46
  .data = NULL,
42
- .flags = RUBY_TYPED_FREE_IMMEDIATELY,
47
+
48
+ #ifdef RUBY_TYPED_FREE_IMMEDIATELY
49
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
50
+ #endif
43
51
  } ;
44
52
 
45
53
  #include "validations.h"
46
54
  #include "func.h"
47
55
 
48
- VALUE _check_(volatile VALUE obj, volatile VALUE args) {
56
+ /*
57
+ Directly check a file with LibmagicRb, without creating any sort of cookies:
58
+
59
+ LibmagicRb.check(file: '/tmp/', db: '/usr/share/file/misc/magic.mgc', mode: LibmagicRb::MAGIC_CHECK) # => "sticky, directory"
60
+
61
+ [file] The key `file:` is the filename to check. Should be a string
62
+
63
+ [db] The key `db:` can be left as nil. Or you can give it the path of the current magic database.
64
+
65
+ [mode] The key `mode` can be any of the LibmagicRb.lsmodes().
66
+ To combine modes you can use `|`. For example:
67
+ `mode: LibmagicRb::MAGIC_CHECK | LibmagicRb::MAGIC_SYMLINK | Libmagic_MAGIC_MIME`
68
+ If `mode` key is nil, it will default to `MAGIC_MIME | MAGIC_CHECK | MAGIC_SYMLINK`
69
+ */
70
+ static VALUE _check_(volatile VALUE obj, volatile VALUE args) {
49
71
  if(!RB_TYPE_P(args, T_HASH)) {
50
72
  rb_raise(rb_eArgError, "Expected hash as argument.") ;
51
73
  }
@@ -103,6 +125,43 @@ VALUE _check_(volatile VALUE obj, volatile VALUE args) {
103
125
  return retVal ;
104
126
  }
105
127
 
128
+ /*
129
+ Intializes a magic cookie that can be used multiple times.
130
+ The benefit of this is to assgign various cookies and change flags of each cookie.
131
+
132
+ For example:
133
+
134
+ > cookie = LibmagicRb.new(file: '/tmp')
135
+ # => #<LibmagicRb:0x000055810139f738 @closed=false, @db=nil, @file="/tmp", @mode=1106>
136
+
137
+ > cookie.check
138
+ # => "inode/directory; charset=binary"
139
+
140
+ > cookie.setflags(LibmagicRb::MAGIC_RAW)
141
+ # => 256
142
+
143
+ > cookie.check
144
+ # => "sticky, directory"
145
+
146
+ > cookie2 = LibmagicRb.new(file: '/usr/share/dict/words')
147
+ # => #<LibmagicRb:0x000055810190a060 @closed=false, @db=nil, @file="/usr/share/dict/words", @mode=1106>
148
+
149
+ > cookie2.check
150
+ # => "text/plain; charset=utf-8"
151
+
152
+ > cookie.close
153
+ # => #<LibmagicRb:0x000055810139f738 @closed=true, @db=nil, @file="/tmp", @mode=256>
154
+
155
+ > cookie.closed?
156
+ # => true
157
+
158
+ > cookie2.closed?
159
+ # => false
160
+
161
+ Here in this example, we can't use cookie, but cookie2 is a different magic_t wrapper, so we can continue using that.
162
+ Flags/modes applied to cookie, will not affect cookie2 as well. Think of them as totally different containers.
163
+ Of course, you must close cookies when you don't need them. Otherwise it can use memories unless GC is triggered.
164
+ */
106
165
  VALUE rb_libmagicRb_initialize(volatile VALUE self, volatile VALUE args) {
107
166
  // Database Path
108
167
  if(!RB_TYPE_P(args, T_HASH)) {
@@ -111,14 +170,11 @@ VALUE rb_libmagicRb_initialize(volatile VALUE self, volatile VALUE args) {
111
170
 
112
171
  VALUE argDBPath = rb_hash_aref(args, ID2SYM(rb_intern("db"))) ;
113
172
 
114
- char *databasePath ;
115
173
  if (RB_TYPE_P(argDBPath, T_NIL)) {
116
- databasePath = NULL ;
117
174
  rb_ivar_set(self, rb_intern("@db"), Qnil) ;
118
175
  } else if (!RB_TYPE_P(argDBPath, T_STRING)) {
119
176
  rb_raise(rb_eArgError, "Database name must be an instance of String.") ;
120
177
  } else {
121
- databasePath = StringValuePtr(argDBPath) ;
122
178
  rb_ivar_set(self, rb_intern("@db"), argDBPath) ;
123
179
  }
124
180
 
@@ -169,6 +225,10 @@ void Init_main() {
169
225
  /*
170
226
  * Libmagic Errors
171
227
  */
228
+
229
+ /*
230
+ Adds ability to check mime-type of a file using the libmagic (magic(4)). It uses native extensions and it's quite performant.
231
+ */
172
232
  VALUE cLibmagicRb = rb_define_class("LibmagicRb", rb_cObject) ;
173
233
 
174
234
  rb_eFileNotFoundError = rb_define_class_under(cLibmagicRb, "FileNotFound", rb_eRuntimeError) ;
@@ -183,9 +243,19 @@ void Init_main() {
183
243
  modes(cLibmagicRb) ;
184
244
  params(cLibmagicRb) ;
185
245
 
186
- char version[6] ;
187
- sprintf(version, "%0.2f", magic_version() / 100.0) ;
188
- rb_define_const(cLibmagicRb, "MAGIC_VERSION", rb_str_new_cstr(version)) ;
246
+
247
+ #if MAGIC_VERSION > 525
248
+ char version[6] ;
249
+ sprintf(version, "%0.2f", magic_version() / 100.0) ;
250
+
251
+ /*
252
+ LibmagicRb::MAGIC_VERSION returns the magic version of the library.
253
+ For older libmagic version, this can be undefined, so this method will return "0" instead.
254
+ */
255
+ rb_define_const(cLibmagicRb, "MAGIC_VERSION", rb_str_new_cstr(version)) ;
256
+ #else
257
+ rb_define_const(cLibmagicRb, "MAGIC_VERSION", rb_str_new_cstr("0")) ;
258
+ #endif
189
259
 
190
260
  /*
191
261
  * Singleton Methods
data/ext/libmagic/modes.h CHANGED
@@ -15,24 +15,57 @@ void modes(volatile VALUE rb_klass) {
15
15
  rb_define_const(rb_klass, "MAGIC_RAW", INT2FIX(MAGIC_RAW)) ;
16
16
  rb_define_const(rb_klass, "MAGIC_ERROR", INT2FIX(MAGIC_ERROR)) ;
17
17
  rb_define_const(rb_klass, "MAGIC_APPLE", INT2FIX(MAGIC_APPLE)) ;
18
+
19
+ #ifdef MAGIC_EXTENSION
18
20
  rb_define_const(rb_klass, "MAGIC_EXTENSION", INT2FIX(MAGIC_EXTENSION)) ;
21
+ #endif
22
+
23
+ #ifdef MAGIC_COMPRESS_TRANSP
19
24
  rb_define_const(rb_klass, "MAGIC_COMPRESS_TRANSP", INT2FIX(MAGIC_COMPRESS_TRANSP)) ;
25
+ #endif
26
+
27
+ #ifdef MAGIC_NO_CHECK_APPTYPE
20
28
  rb_define_const(rb_klass, "MAGIC_NO_CHECK_APPTYPE", INT2FIX(MAGIC_NO_CHECK_APPTYPE)) ;
29
+ #endif
30
+
31
+ #ifdef MAGIC_NO_CHECK_CDF
21
32
  rb_define_const(rb_klass, "MAGIC_NO_CHECK_CDF", INT2FIX(MAGIC_NO_CHECK_CDF)) ;
33
+ #endif
34
+
35
+ #ifdef MAGIC_NO_CHECK_COMPRESS
22
36
  rb_define_const(rb_klass, "MAGIC_NO_CHECK_COMPRESS", INT2FIX(MAGIC_NO_CHECK_COMPRESS)) ;
37
+ #endif
38
+
39
+ #ifdef MAGIC_NO_CHECK_ELF
23
40
  rb_define_const(rb_klass, "MAGIC_NO_CHECK_ELF", INT2FIX(MAGIC_NO_CHECK_ELF)) ;
41
+ #endif
42
+
43
+ #ifdef MAGIC_NO_CHECK_ENCODING
24
44
  rb_define_const(rb_klass, "MAGIC_NO_CHECK_ENCODING", INT2FIX(MAGIC_NO_CHECK_ENCODING)) ;
45
+ #endif
46
+
47
+ #ifdef MAGIC_NO_CHECK_SOFT
25
48
  rb_define_const(rb_klass, "MAGIC_NO_CHECK_SOFT", INT2FIX(MAGIC_NO_CHECK_SOFT)) ;
49
+ #endif
50
+
51
+ #ifdef MAGIC_NO_CHECK_TAR
26
52
  rb_define_const(rb_klass, "MAGIC_NO_CHECK_TAR", INT2FIX(MAGIC_NO_CHECK_TAR)) ;
53
+ #endif
54
+
55
+ #ifdef MAGIC_NO_CHECK_TEXT
27
56
  rb_define_const(rb_klass, "MAGIC_NO_CHECK_TEXT", INT2FIX(MAGIC_NO_CHECK_TEXT)) ;
57
+ #endif
58
+
59
+ #ifdef MAGIC_NO_CHECK_TOKENS
28
60
  rb_define_const(rb_klass, "MAGIC_NO_CHECK_TOKENS", INT2FIX(MAGIC_NO_CHECK_TOKENS)) ;
61
+ #endif
29
62
 
30
63
  #ifdef MAGIC_NO_CHECK_JSON
31
- rb_define_const(rb_klass, "MAGIC_NO_CHECK_JSON", INT2FIX(MAGIC_NO_CHECK_JSON)) ;
64
+ rb_define_const(rb_klass, "MAGIC_NO_CHECK_JSON", INT2FIX(MAGIC_NO_CHECK_JSON)) ;
32
65
  #endif
33
66
 
34
67
  #ifdef MAGIC_NO_CHECK_CSV
35
- rb_define_const(rb_klass, "MAGIC_NO_CHECK_CSV", INT2FIX(MAGIC_NO_CHECK_CSV)) ;
68
+ rb_define_const(rb_klass, "MAGIC_NO_CHECK_CSV", INT2FIX(MAGIC_NO_CHECK_CSV)) ;
36
69
  #endif
37
70
  }
38
71
 
@@ -53,24 +86,56 @@ VALUE lsmodes(volatile VALUE obj) {
53
86
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_RAW")), INT2FIX(MAGIC_RAW)) ;
54
87
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_ERROR")), INT2FIX(MAGIC_ERROR)) ;
55
88
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_APPLE")), INT2FIX(MAGIC_APPLE)) ;
89
+ #ifdef MAGIC_EXTENSION
56
90
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_EXTENSION")), INT2FIX(MAGIC_EXTENSION)) ;
91
+ #endif
92
+
93
+ #ifdef MAGIC_COMPRESS_TRANSP
57
94
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_COMPRESS_TRANSP")), INT2FIX(MAGIC_COMPRESS_TRANSP)) ;
95
+ #endif
96
+
97
+ #ifdef MAGIC_NO_CHECK_APPTYPE
58
98
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_NO_CHECK_APPTYPE")), INT2FIX(MAGIC_NO_CHECK_APPTYPE)) ;
99
+ #endif
100
+
101
+ #ifdef MAGIC_NO_CHECK_CDF
59
102
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_NO_CHECK_CDF")), INT2FIX(MAGIC_NO_CHECK_CDF)) ;
103
+ #endif
104
+
105
+ #ifdef MAGIC_NO_CHECK_COMPRESS
60
106
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_NO_CHECK_COMPRESS")), INT2FIX(MAGIC_NO_CHECK_COMPRESS)) ;
107
+ #endif
108
+
109
+ #ifdef MAGIC_NO_CHECK_ELF
61
110
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_NO_CHECK_ELF")), INT2FIX(MAGIC_NO_CHECK_ELF)) ;
111
+ #endif
112
+
113
+ #ifdef MAGIC_NO_CHECK_ENCODING
62
114
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_NO_CHECK_ENCODING")), INT2FIX(MAGIC_NO_CHECK_ENCODING)) ;
115
+ #endif
116
+
117
+ #ifdef MAGIC_NO_CHECK_SOFT
63
118
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_NO_CHECK_SOFT")), INT2FIX(MAGIC_NO_CHECK_SOFT)) ;
119
+ #endif
120
+
121
+ #ifdef MAGIC_NO_CHECK_TAR
64
122
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_NO_CHECK_TAR")), INT2FIX(MAGIC_NO_CHECK_TAR)) ;
123
+ #endif
124
+
125
+ #ifdef MAGIC_NO_CHECK_TEXT
65
126
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_NO_CHECK_TEXT")), INT2FIX(MAGIC_NO_CHECK_TEXT)) ;
127
+ #endif
128
+
129
+ #ifdef MAGIC_NO_CHECK_TOKENS
66
130
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_NO_CHECK_TOKENS")), INT2FIX(MAGIC_NO_CHECK_TOKENS)) ;
131
+ #endif
67
132
 
68
133
  #ifdef MAGIC_NO_CHECK_CSV
69
- rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_NO_CHECK_CSV")), INT2FIX(MAGIC_NO_CHECK_CSV)) ;
134
+ rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_NO_CHECK_CSV")), INT2FIX(MAGIC_NO_CHECK_CSV)) ;
70
135
  #endif
71
136
 
72
137
  #ifdef MAGIC_NO_CHECK_CSV
73
- rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_NO_CHECK_JSON")), INT2FIX(MAGIC_NO_CHECK_JSON)) ;
138
+ rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_NO_CHECK_JSON")), INT2FIX(MAGIC_NO_CHECK_JSON)) ;
74
139
  #endif
75
140
 
76
141
  return hash ;
@@ -1,28 +1,62 @@
1
1
  void params(volatile VALUE rb_klass) {
2
+ #ifdef MAGIC_PARAM_INDIR_MAX
2
3
  rb_define_const(rb_klass, "MAGIC_PARAM_INDIR_MAX", UINT2NUM(MAGIC_PARAM_INDIR_MAX)) ;
4
+ #endif
5
+
6
+ #ifdef MAGIC_PARAM_NAME_MAX
3
7
  rb_define_const(rb_klass, "MAGIC_PARAM_NAME_MAX", UINT2NUM(MAGIC_PARAM_NAME_MAX)) ;
8
+ #endif
9
+
10
+ #ifdef MAGIC_PARAM_ELF_NOTES_MAX
4
11
  rb_define_const(rb_klass, "MAGIC_PARAM_ELF_NOTES_MAX", UINT2NUM(MAGIC_PARAM_ELF_NOTES_MAX)) ;
12
+ #endif
13
+
14
+ #ifdef MAGIC_PARAM_ELF_PHNUM_MAX
5
15
  rb_define_const(rb_klass, "MAGIC_PARAM_ELF_PHNUM_MAX", UINT2NUM(MAGIC_PARAM_ELF_PHNUM_MAX)) ;
16
+ #endif
17
+
18
+ #ifdef MAGIC_PARAM_ELF_SHNUM_MAX
6
19
  rb_define_const(rb_klass, "MAGIC_PARAM_ELF_SHNUM_MAX", UINT2NUM(MAGIC_PARAM_ELF_SHNUM_MAX)) ;
20
+ #endif
21
+
22
+ #ifdef MAGIC_PARAM_REGEX_MAX
7
23
  rb_define_const(rb_klass, "MAGIC_PARAM_REGEX_MAX", UINT2NUM(MAGIC_PARAM_REGEX_MAX)) ;
24
+ #endif
8
25
 
9
26
  #ifdef MAGIC_PARAM_BYTES_MAX
10
- rb_define_const(rb_klass, "MAGIC_PARAM_BYTES_MAX", UINT2NUM(MAGIC_PARAM_BYTES_MAX)) ;
27
+ rb_define_const(rb_klass, "MAGIC_PARAM_BYTES_MAX", UINT2NUM(MAGIC_PARAM_BYTES_MAX)) ;
11
28
  #endif
12
29
  }
13
30
 
14
31
  VALUE lsparams(volatile VALUE obj) {
15
32
  VALUE hash = rb_hash_new() ;
16
33
 
34
+ #ifdef MAGIC_PARAM_INDIR_MAX
17
35
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_PARAM_INDIR_MAX")), UINT2NUM(MAGIC_PARAM_INDIR_MAX)) ;
36
+ #endif
37
+
38
+ #ifdef MAGIC_PARAM_NAME_MAX
18
39
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_PARAM_NAME_MAX")), UINT2NUM(MAGIC_PARAM_NAME_MAX)) ;
40
+ #endif
41
+
42
+ #ifdef MAGIC_PARAM_ELF_NOTES_MAX
19
43
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_PARAM_ELF_NOTES_MAX")), UINT2NUM(MAGIC_PARAM_ELF_NOTES_MAX)) ;
44
+ #endif
45
+
46
+ #ifdef MAGIC_PARAM_ELF_PHNUM_MAX
20
47
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_PARAM_ELF_PHNUM_MAX")), UINT2NUM(MAGIC_PARAM_ELF_PHNUM_MAX)) ;
48
+ #endif
49
+
50
+ #ifdef MAGIC_PARAM_ELF_SHNUM_MAX
21
51
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_PARAM_ELF_SHNUM_MAX")), UINT2NUM(MAGIC_PARAM_ELF_SHNUM_MAX)) ;
52
+ #endif
53
+
54
+ #ifdef MAGIC_PARAM_REGEX_MAX
22
55
  rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_PARAM_REGEX_MAX")), UINT2NUM(MAGIC_PARAM_REGEX_MAX)) ;
56
+ #endif
23
57
 
24
58
  #ifdef MAGIC_PARAM_BYTES_MAX
25
- rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_PARAM_BYTES_MAX")), UINT2NUM(MAGIC_PARAM_BYTES_MAX)) ;
59
+ rb_hash_aset(hash, ID2SYM(rb_intern("MAGIC_PARAM_BYTES_MAX")), UINT2NUM(MAGIC_PARAM_BYTES_MAX)) ;
26
60
  #endif
27
61
 
28
62
  return hash ;
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class LibmagicRb
4
- VERSION = "0.1.1-alpha"
4
+ VERSION = "0.1.2-gamma"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libmagic_rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1.pre.alpha
4
+ version: 0.1.2.pre.gamma
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cybergizer
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-08-19 00:00:00.000000000 Z
11
+ date: 2021-09-06 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Check filetype with libmagic
14
14
  email: