libmagic_rb 0.1.1 → 0.1.2
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.
- checksums.yaml +4 -4
- data/README.md +41 -9
- data/ext/libmagic/func.h +175 -3
- data/ext/libmagic/magic.c +67 -2
- data/lib/libmagic_rb/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: add88dc48d3eda81cd55f1eafd163822b50452852b1f0ae0121b3de36e2f5588
|
4
|
+
data.tar.gz: 60b7af94ac6e809f16ae22b1c7aac8eb3eab68b4be76c2437217bc6da32be58a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d694f12d7d3211dc40e0e1eedbac222bb232a529f5ac9a27fdc3a7f58f2c0238cebacff4ed4490931abc0fd46baee72aa84402863809b938fe9d65f9bf781c61
|
7
|
+
data.tar.gz: 8a2f6b16efe5644f66cbe45dab50b0ef671592fd0d586cd2a51edc09bdd0b993c903eed617f748567e50b1db4c6c02a36577af98b653fa9a1b5466f5c615ead2
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
# LibmagicRb
|
1
|
+
# LibmagicRb [](https://rubygems.org/gems/libmagic_rb) 
|
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
|
|
@@ -17,31 +18,62 @@ You also need Ruby > 1.9.0 in order to run this gem.
|
|
17
18
|
|
18
19
|
With that info in mind, let's continue to the installation part for your Linux distributions...
|
19
20
|
|
20
|
-
#### Arch / Manjaro / Archlabs & other Arch
|
21
|
+
#### Arch / Manjaro / Archlabs / Garuda Linux / Hefftor Linux & other Arch Based Linux
|
21
22
|
|
22
23
|
```
|
23
|
-
# pacman -S file gcc make
|
24
|
+
# pacman -S ruby file gcc make --needed
|
24
25
|
```
|
25
26
|
|
26
|
-
#### Debian / Ubuntu / Linux Mint / RaspberryPi OS & other Debian
|
27
|
+
#### Debian / Ubuntu / Linux Mint / Deepin / Pop!_OS / RaspberryPi OS & other Debian Based Linux
|
27
28
|
|
28
29
|
```
|
29
|
-
# apt install libmagic-dev ruby-dev gcc make
|
30
|
+
# apt install ruby libmagic-dev ruby-dev gcc make
|
30
31
|
```
|
31
32
|
|
32
|
-
#### Fedora / Amazon Linux / CentOS & Other RedHat
|
33
|
+
#### Fedora / Amazon Linux / CentOS & Other RedHat Based Linux
|
33
34
|
|
34
35
|
```
|
35
|
-
# yum install file-devel ruby-devel gcc make
|
36
|
+
# yum install ruby file-devel ruby-devel gcc make
|
36
37
|
```
|
37
38
|
|
38
39
|
#### OpenSUSE
|
39
40
|
|
40
41
|
```
|
41
|
-
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
|
+
|
42
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
|
70
|
+
```
|
71
|
+
|
72
|
+
[ Source: [ eparreno/gist:1845561 ](https://gist.github.com/eparreno/1845561) ]
|
73
|
+
|
74
|
+
#### Windows
|
43
75
|
|
44
|
-
|
76
|
+
Windows is currently not tested, hence the support is unknown.
|
45
77
|
|
46
78
|
## Installation
|
47
79
|
|
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,6 +94,18 @@ 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
110
|
#if MAGIC_VERSION > 525
|
56
111
|
RB_UNWRAP(cookie) ;
|
@@ -66,6 +121,27 @@ VALUE _getParamGlobal_(volatile VALUE self, volatile VALUE param) {
|
|
66
121
|
#endif
|
67
122
|
}
|
68
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
|
+
|
69
145
|
VALUE _setParamGlobal_(volatile VALUE self, volatile VALUE param, volatile VALUE paramVal) {
|
70
146
|
#if MAGIC_VERSION > 525
|
71
147
|
unsigned int _param = NUM2UINT(param) ;
|
@@ -85,25 +161,121 @@ VALUE _setParamGlobal_(volatile VALUE self, volatile VALUE param, volatile VALUE
|
|
85
161
|
#endif
|
86
162
|
}
|
87
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
|
+
|
88
183
|
VALUE _bufferGlobal_(volatile VALUE self, volatile VALUE string) {
|
89
184
|
RB_UNWRAP(cookie) ;
|
90
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
|
+
|
91
196
|
char *buffer = StringValuePtr(string) ;
|
92
|
-
const char *buf = magic_buffer(*cookie, buffer,
|
197
|
+
const char *buf = magic_buffer(*cookie, buffer, strlen(buffer)) ;
|
93
198
|
|
94
|
-
return rb_str_new_cstr(buf) ;
|
199
|
+
return buf ? rb_str_new_cstr(buf) : Qnil ;
|
95
200
|
}
|
96
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
|
+
|
97
232
|
VALUE _listGlobal_(volatile VALUE self) {
|
98
233
|
RB_UNWRAP(cookie) ;
|
99
234
|
|
100
235
|
VALUE db = rb_iv_get(self, "@db") ;
|
101
|
-
char *database = StringValuePtr(db) ;
|
102
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) ;
|
103
243
|
int status = magic_list(*cookie, database) ;
|
244
|
+
|
104
245
|
return INT2FIX(status) ;
|
105
246
|
}
|
106
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
|
+
|
107
279
|
VALUE _setflagsGlobal_(volatile VALUE self, volatile VALUE flags) {
|
108
280
|
unsigned int flag = NUM2UINT(flags) ;
|
109
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
|
/*
|
@@ -43,13 +44,30 @@ static rb_data_type_t fileType = {
|
|
43
44
|
},
|
44
45
|
|
45
46
|
.data = NULL,
|
46
|
-
|
47
|
+
|
48
|
+
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
49
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
50
|
+
#endif
|
47
51
|
} ;
|
48
52
|
|
49
53
|
#include "validations.h"
|
50
54
|
#include "func.h"
|
51
55
|
|
52
|
-
|
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) {
|
53
71
|
if(!RB_TYPE_P(args, T_HASH)) {
|
54
72
|
rb_raise(rb_eArgError, "Expected hash as argument.") ;
|
55
73
|
}
|
@@ -107,6 +125,43 @@ VALUE _check_(volatile VALUE obj, volatile VALUE args) {
|
|
107
125
|
return retVal ;
|
108
126
|
}
|
109
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
|
+
*/
|
110
165
|
VALUE rb_libmagicRb_initialize(volatile VALUE self, volatile VALUE args) {
|
111
166
|
// Database Path
|
112
167
|
if(!RB_TYPE_P(args, T_HASH)) {
|
@@ -170,6 +225,10 @@ void Init_main() {
|
|
170
225
|
/*
|
171
226
|
* Libmagic Errors
|
172
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
|
+
*/
|
173
232
|
VALUE cLibmagicRb = rb_define_class("LibmagicRb", rb_cObject) ;
|
174
233
|
|
175
234
|
rb_eFileNotFoundError = rb_define_class_under(cLibmagicRb, "FileNotFound", rb_eRuntimeError) ;
|
@@ -184,9 +243,15 @@ void Init_main() {
|
|
184
243
|
modes(cLibmagicRb) ;
|
185
244
|
params(cLibmagicRb) ;
|
186
245
|
|
246
|
+
|
187
247
|
#if MAGIC_VERSION > 525
|
188
248
|
char version[6] ;
|
189
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
|
+
*/
|
190
255
|
rb_define_const(cLibmagicRb, "MAGIC_VERSION", rb_str_new_cstr(version)) ;
|
191
256
|
#else
|
192
257
|
rb_define_const(cLibmagicRb, "MAGIC_VERSION", rb_str_new_cstr("0")) ;
|
data/lib/libmagic_rb/version.rb
CHANGED
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.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cybergizer
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-06 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Check filetype with libmagic
|
14
14
|
email:
|