ruby-magic 0.0.1 → 0.4.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.
- checksums.yaml +5 -5
- data/AUTHORS +1 -1
- data/CHANGELOG.md +60 -0
- data/CONTRIBUTORS.md +17 -0
- data/COPYRIGHT +1 -1
- data/NOTICE +505 -0
- data/README.md +49 -0
- data/dependencies.yml +93 -0
- data/ext/magic/common.h +130 -59
- data/ext/magic/extconf.rb +404 -64
- data/ext/magic/functions.c +265 -187
- data/ext/magic/functions.h +46 -79
- data/ext/magic/ruby-magic.c +1288 -641
- data/ext/magic/ruby-magic.h +383 -173
- data/kwilczynski-public.pem +25 -0
- data/lib/magic.rb +86 -87
- data/lib/magic/core/file.rb +8 -66
- data/lib/magic/core/string.rb +4 -47
- data/lib/magic/version.rb +14 -48
- data/patches/libmagic/0001-Don-t-attempt-to-build-tests-documentation-and-Python-bindings.patch +44 -0
- data/ports/archives/file-5.39.tar.gz +0 -0
- metadata +36 -99
- data/CHANGES +0 -5
- data/CHANGES.rdoc +0 -5
- data/README +0 -1
- data/README.rdoc +0 -7
- data/Rakefile +0 -78
- data/TODO +0 -21
- data/VERSION +0 -1
- data/bin/magic +0 -33
- data/ruby-magic.gemspec +0 -68
- data/test/test_constants.rb +0 -47
- data/test/test_magic.rb +0 -260
data/ext/magic/functions.h
CHANGED
@@ -1,23 +1,3 @@
|
|
1
|
-
/* :enddoc: */
|
2
|
-
|
3
|
-
/*
|
4
|
-
* functions.h
|
5
|
-
*
|
6
|
-
* Copyright 2013-2014 Krzysztof Wilczynski
|
7
|
-
*
|
8
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
9
|
-
* you may not use this file except in compliance with the License.
|
10
|
-
* You may obtain a copy of the License at
|
11
|
-
*
|
12
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
13
|
-
*
|
14
|
-
* Unless required by applicable law or agreed to in writing, software
|
15
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
-
* See the License for the specific language governing permissions and
|
18
|
-
* limitations under the License.
|
19
|
-
*/
|
20
|
-
|
21
1
|
#if !defined(_FUNCTIONS_H)
|
22
2
|
#define _FUNCTIONS_H 1
|
23
3
|
|
@@ -27,67 +7,56 @@ extern "C" {
|
|
27
7
|
|
28
8
|
#include "common.h"
|
29
9
|
|
30
|
-
#
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
else { \
|
59
|
-
SUPPRESS_EVERYTHING(f, r, __VA_ARGS__); \
|
60
|
-
} \
|
61
|
-
} while(0)
|
62
|
-
|
63
|
-
struct file_data {
|
64
|
-
int old_fd;
|
65
|
-
int new_fd;
|
66
|
-
fpos_t position;
|
67
|
-
};
|
68
|
-
|
69
|
-
typedef struct file_data file_data_t;
|
70
|
-
|
71
|
-
struct save {
|
72
|
-
int status;
|
73
|
-
union {
|
74
|
-
file_data_t file;
|
75
|
-
char *locale;
|
76
|
-
} data;
|
77
|
-
};
|
78
|
-
|
79
|
-
typedef struct save save_t;
|
10
|
+
#define MAGIC_FUNCTION(f, r, x, ...) \
|
11
|
+
do { \
|
12
|
+
if ((x) & MAGIC_DEBUG) \
|
13
|
+
r = f(__VA_ARGS__); \
|
14
|
+
else { \
|
15
|
+
save_t __##f; \
|
16
|
+
override_error_output(&(__##f)); \
|
17
|
+
r = f(__VA_ARGS__); \
|
18
|
+
restore_error_output(&(__##f)); \
|
19
|
+
} \
|
20
|
+
} while(0)
|
21
|
+
|
22
|
+
typedef struct file_data {
|
23
|
+
fpos_t position;
|
24
|
+
int old_fd;
|
25
|
+
int new_fd;
|
26
|
+
} file_data_t;
|
27
|
+
|
28
|
+
typedef struct save {
|
29
|
+
file_data_t file;
|
30
|
+
int status;
|
31
|
+
} save_t;
|
32
|
+
|
33
|
+
extern magic_t magic_open_wrapper(int flags);
|
34
|
+
extern void magic_close_wrapper(magic_t magic);
|
35
|
+
|
36
|
+
extern const char* magic_error_wrapper(magic_t magic);
|
37
|
+
extern int magic_errno_wrapper(magic_t magic);
|
80
38
|
|
81
39
|
extern const char* magic_getpath_wrapper(void);
|
82
40
|
|
83
|
-
extern int
|
84
|
-
extern int
|
85
|
-
|
86
|
-
|
41
|
+
extern int magic_getparam_wrapper(magic_t magic, int parameter, void *value);
|
42
|
+
extern int magic_setparam_wrapper(magic_t magic, int parameter,
|
43
|
+
const void *value);
|
44
|
+
|
45
|
+
extern int magic_getflags_wrapper(magic_t magic);
|
46
|
+
extern int magic_setflags_wrapper(magic_t magic, int flags);
|
87
47
|
|
88
|
-
extern
|
89
|
-
extern
|
90
|
-
|
48
|
+
extern int magic_load_wrapper(magic_t magic, const char *magic_file, int flags);
|
49
|
+
extern int magic_load_buffers_wrapper(magic_t magic, void **buffers,
|
50
|
+
size_t *sizes, size_t count, int flags);
|
51
|
+
|
52
|
+
extern int magic_compile_wrapper(magic_t magic, const char *magic_file, int flags);
|
53
|
+
extern int magic_check_wrapper(magic_t magic, const char *magic_file, int flags);
|
54
|
+
|
55
|
+
extern const char* magic_file_wrapper(magic_t magic, const char *filename,
|
56
|
+
int flags);
|
57
|
+
extern const char* magic_buffer_wrapper(magic_t magic, const void *buffer,
|
58
|
+
size_t size, int flags);
|
59
|
+
extern const char* magic_descriptor_wrapper(magic_t magic, int fd, int flags);
|
91
60
|
|
92
61
|
extern int magic_version_wrapper(void);
|
93
62
|
|
@@ -96,5 +65,3 @@ extern int magic_version_wrapper(void);
|
|
96
65
|
#endif
|
97
66
|
|
98
67
|
#endif /* _FUNCTIONS_H */
|
99
|
-
|
100
|
-
/* vim: set ts=8 sw=4 sts=2 et : */
|
data/ext/magic/ruby-magic.c
CHANGED
@@ -1,973 +1,1620 @@
|
|
1
|
-
|
1
|
+
#if defined(__cplusplus)
|
2
|
+
extern "C" {
|
3
|
+
#endif
|
4
|
+
|
5
|
+
#include "ruby-magic.h"
|
2
6
|
|
3
7
|
/*
|
4
|
-
*
|
8
|
+
* call-seq:
|
9
|
+
* Magic.do_not_auto_load -> boolean
|
5
10
|
*
|
6
|
-
*
|
11
|
+
* Returns +true+ if the global +do_not_auto_load+ flag is set, or +false+
|
12
|
+
* otherwise.
|
7
13
|
*
|
8
|
-
*
|
9
|
-
* you may not use this file except in compliance with the License.
|
10
|
-
* You may obtain a copy of the License at
|
14
|
+
* Example:
|
11
15
|
*
|
12
|
-
*
|
16
|
+
* Magic.do_not_auto_load #=> false
|
17
|
+
* Magic.do_not_auto_load = true #=> true
|
18
|
+
* Magic.do_not_auto_load #=> true
|
13
19
|
*
|
14
|
-
*
|
15
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
-
* See the License for the specific language governing permissions and
|
18
|
-
* limitations under the License.
|
20
|
+
* See also: Magic::new, Magic#loaded?, Magic#load and Magic#load_buffers
|
19
21
|
*/
|
22
|
+
VALUE
|
23
|
+
rb_mgc_get_do_not_auto_load_global(RB_UNUSED_VAR(VALUE object))
|
24
|
+
{
|
25
|
+
return CBOOL2RVAL(rb_mgc_do_not_auto_load);
|
26
|
+
}
|
20
27
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
static VALUE magic_library_error(VALUE klass, void *data);
|
56
|
-
static VALUE magic_generic_error(VALUE klass, int magic_errno,
|
57
|
-
const char *magic_error);
|
58
|
-
|
59
|
-
static VALUE magic_lock(VALUE object, VALUE (*function)(ANYARGS), void *data);
|
60
|
-
static VALUE magic_unlock(VALUE object);
|
28
|
+
/*
|
29
|
+
* call-seq:
|
30
|
+
* Magic.do_not_auto_load= ( boolean ) -> boolean
|
31
|
+
*
|
32
|
+
* Sets the global +do_not_auto_load+ flag for the Magic object and each of the
|
33
|
+
* Magic object instances. This flag can be used to disable automatic loading of
|
34
|
+
* the Magic database files.
|
35
|
+
*
|
36
|
+
* Returns +true+ if the global +do_not_auto_load+ flag is set, or +false+
|
37
|
+
* otherwise.
|
38
|
+
*
|
39
|
+
* Example:
|
40
|
+
*
|
41
|
+
* Magic.do_not_auto_load #=> false
|
42
|
+
* Magic.do_not_auto_load = true #=> true
|
43
|
+
* Magic.do_not_auto_load #=> true
|
44
|
+
*
|
45
|
+
* Example:
|
46
|
+
*
|
47
|
+
* Magic.do_not_auto_load = true #=> true
|
48
|
+
* magic = Magic.new
|
49
|
+
* magic.loaded? #=> false
|
50
|
+
* magic.load_buffers(File.read(magic.paths[0] + ".mgc")) #=> nil
|
51
|
+
* magic.loaded? #=> true
|
52
|
+
*
|
53
|
+
* See also: Magic::new, Magic#loaded?, Magic#load and Magic#load_buffers
|
54
|
+
*/
|
55
|
+
VALUE
|
56
|
+
rb_mgc_set_do_not_auto_load_global(RB_UNUSED_VAR(VALUE object), VALUE value)
|
57
|
+
{
|
58
|
+
rb_mgc_do_not_auto_load = RVAL2CBOOL(value);
|
59
|
+
return value;
|
60
|
+
}
|
61
61
|
|
62
|
-
|
62
|
+
/*
|
63
|
+
* call-seq:
|
64
|
+
* Magic.do_not_stop_on_error -> boolean
|
65
|
+
*
|
66
|
+
* Returns +true+ if the global +do_not_stop_on_error+ flag is set, or +false+
|
67
|
+
* otherwise.
|
68
|
+
*
|
69
|
+
* Example:
|
70
|
+
*
|
71
|
+
* Magic.do_not_stop_on_error #=> false
|
72
|
+
* Magic.do_not_stop_on_error = true #=> true
|
73
|
+
* Magic.do_not_stop_on_error #=> true
|
74
|
+
*
|
75
|
+
* See also: Magic::new, Magic::open and Magic#do_not_stop_on_error
|
76
|
+
*/
|
77
|
+
VALUE
|
78
|
+
rb_mgc_get_do_not_stop_on_error_global(RB_UNUSED_VAR(VALUE object))
|
79
|
+
{
|
80
|
+
return CBOOL2RVAL(rb_mgc_do_not_stop_on_error);
|
81
|
+
}
|
63
82
|
|
64
|
-
/*
|
83
|
+
/*
|
84
|
+
* call-seq:
|
85
|
+
* Magic.do_not_stop_on_error= (boolean) -> boolean
|
86
|
+
*
|
87
|
+
* Example:
|
88
|
+
*
|
89
|
+
* Magic.do_not_stop_on_error #=> false
|
90
|
+
* Magic.do_not_stop_on_error = true #=> true
|
91
|
+
* Magic.do_not_stop_on_error #=> true
|
92
|
+
*
|
93
|
+
* See also: Magic::new, Magic::open and Magic#do_not_stop_on_error
|
94
|
+
*/
|
95
|
+
VALUE
|
96
|
+
rb_mgc_set_do_not_stop_on_error_global(RB_UNUSED_VAR(VALUE object), VALUE value)
|
97
|
+
{
|
98
|
+
rb_mgc_do_not_stop_on_error = RVAL2CBOOL(value);
|
99
|
+
return value;
|
100
|
+
}
|
65
101
|
|
66
102
|
/*
|
67
103
|
* call-seq:
|
68
|
-
* Magic.new
|
69
|
-
* Magic.new(
|
70
|
-
* Magic.new( array )
|
104
|
+
* Magic.new -> self
|
105
|
+
* Magic.new( string, ... ) -> self
|
106
|
+
* Magic.new( array ) -> self
|
71
107
|
*
|
72
108
|
* Opens the underlying _Magic_ database and returns a new _Magic_.
|
73
109
|
*
|
74
110
|
* Example:
|
75
111
|
*
|
76
|
-
* magic = Magic.new
|
77
|
-
*
|
78
|
-
* Will raise <i>Magic::LibraryError</i> exception if, or
|
79
|
-
* <i>Magic::MagicError</i> exception if, or
|
112
|
+
* magic = Magic.new
|
113
|
+
* magic.class #=> Magic
|
80
114
|
*
|
81
115
|
* See also: Magic::open, Magic::mime, Magic::type, Magic::encoding, Magic::compile and Magic::check
|
82
116
|
*/
|
83
117
|
VALUE
|
84
118
|
rb_mgc_initialize(VALUE object, VALUE arguments)
|
85
119
|
{
|
86
|
-
|
87
|
-
|
88
|
-
magic_arguments_t ma;
|
89
|
-
const char *klass = NULL;
|
120
|
+
magic_object_t *mo;
|
121
|
+
const char *klass = "Magic";
|
90
122
|
|
91
|
-
|
92
|
-
|
123
|
+
if (!NIL_P(object))
|
124
|
+
klass = rb_obj_classname(object);
|
93
125
|
|
94
|
-
|
95
|
-
|
96
|
-
|
126
|
+
if (rb_block_given_p())
|
127
|
+
MAGIC_WARNING(0, "%s::new() does not take block; use %s::open() instead",
|
128
|
+
klass, klass);
|
97
129
|
|
98
|
-
|
99
|
-
|
100
|
-
}
|
130
|
+
if(RTEST(rb_eval_string("ENV['MAGIC_DO_NOT_STOP_ON_ERROR']")))
|
131
|
+
rb_mgc_do_not_stop_on_error = 1;
|
101
132
|
|
102
|
-
|
103
|
-
|
133
|
+
if(RTEST(rb_eval_string("ENV['MAGIC_DO_NOT_AUTOLOAD']")))
|
134
|
+
rb_mgc_do_not_auto_load = 1;
|
104
135
|
|
105
|
-
|
136
|
+
MAGIC_OBJECT(mo);
|
137
|
+
mo->stop_on_errors = 1;
|
138
|
+
if (rb_mgc_do_not_stop_on_error)
|
139
|
+
mo->stop_on_errors = 0;
|
106
140
|
|
107
|
-
|
141
|
+
mo->mutex = rb_class_new_instance(0, 0, rb_const_get(rb_cObject,
|
142
|
+
rb_intern("Mutex")));
|
108
143
|
|
109
|
-
|
110
|
-
|
144
|
+
magic_set_flags(object, INT2NUM(MAGIC_NONE));
|
145
|
+
magic_set_paths(object, RARRAY_EMPTY);
|
111
146
|
|
112
|
-
|
113
|
-
|
147
|
+
if (rb_mgc_do_not_auto_load) {
|
148
|
+
if (!RARRAY_EMPTY_P(arguments))
|
149
|
+
MAGIC_WARNING(1, "%s::do_not_auto_load is set; using %s#new() to load "
|
150
|
+
"Magic database from a file will have no effect",
|
151
|
+
klass, klass);
|
152
|
+
return object;
|
153
|
+
}
|
114
154
|
|
115
|
-
|
155
|
+
rb_mgc_load(object, arguments);
|
156
|
+
return object;
|
116
157
|
}
|
117
158
|
|
118
159
|
/*
|
119
160
|
* call-seq:
|
120
|
-
* magic.
|
121
|
-
*
|
122
|
-
* Closes the underlying _Magic_ database.
|
161
|
+
* magic.do_not_stop_on_error -> boolean
|
123
162
|
*
|
124
|
-
*
|
125
|
-
*
|
126
|
-
* magic = Magic.new #=> #<Magic:0x007f8fdc012e58>
|
127
|
-
* magic.close #=> nil
|
128
|
-
*
|
129
|
-
* See also: Magic#closed?
|
163
|
+
* See also: Magic::new, Magic::open and Magic::do_not_stop_on_error
|
130
164
|
*/
|
131
165
|
VALUE
|
132
|
-
|
166
|
+
rb_mgc_get_do_not_stop_on_error(VALUE object)
|
133
167
|
{
|
134
|
-
|
168
|
+
magic_object_t *mo;
|
135
169
|
|
136
|
-
|
170
|
+
MAGIC_CHECK_OPEN(object);
|
171
|
+
MAGIC_OBJECT(mo);
|
137
172
|
|
138
|
-
|
139
|
-
|
173
|
+
return CBOOL2RVAL(!mo->stop_on_errors);
|
174
|
+
}
|
175
|
+
|
176
|
+
/*
|
177
|
+
* call-seq:
|
178
|
+
* magic.do_not_stop_on_error= ( boolean ) -> boolean
|
179
|
+
*
|
180
|
+
* See also: Magic::new, Magic::open and Magic::do_not_stop_on_error
|
181
|
+
*/
|
182
|
+
VALUE
|
183
|
+
rb_mgc_set_do_not_stop_on_error(VALUE object, VALUE value)
|
184
|
+
{
|
185
|
+
magic_object_t *mo;
|
140
186
|
|
141
|
-
|
142
|
-
|
143
|
-
}
|
144
|
-
}
|
187
|
+
MAGIC_CHECK_OPEN(object);
|
188
|
+
MAGIC_OBJECT(mo);
|
145
189
|
|
146
|
-
|
190
|
+
mo->stop_on_errors = !RVAL2CBOOL(value);
|
191
|
+
return value;
|
147
192
|
}
|
148
193
|
|
149
194
|
/*
|
150
195
|
* call-seq:
|
151
|
-
* magic.
|
196
|
+
* magic.open? -> true or false
|
152
197
|
*
|
153
198
|
* Returns +true+ if the underlying _Magic_ database is open,
|
154
199
|
* or +false+ otherwise.
|
155
200
|
*
|
156
201
|
* Example:
|
157
202
|
*
|
158
|
-
* magic = Magic.new
|
159
|
-
* magic.
|
160
|
-
* magic.close
|
161
|
-
* magic.
|
203
|
+
* magic = Magic.new
|
204
|
+
* magic.open? #=> true
|
205
|
+
* magic.close #=> nil
|
206
|
+
* magic.open? #=> false
|
162
207
|
*
|
163
|
-
* See also: Magic#close
|
208
|
+
* See also: Magic#close?, Magic#close and Magic#new
|
164
209
|
*/
|
165
210
|
VALUE
|
166
|
-
|
211
|
+
rb_mgc_open_p(VALUE object)
|
167
212
|
{
|
168
|
-
|
169
|
-
|
170
|
-
MAGIC_COOKIE(cookie);
|
171
|
-
|
172
|
-
if (DATA_P(object) && DATA_PTR(object) && cookie) {
|
173
|
-
return Qfalse;
|
174
|
-
}
|
175
|
-
|
176
|
-
return Qtrue;
|
213
|
+
return MAGIC_CLOSED_P(object) ? Qfalse : Qtrue;
|
177
214
|
}
|
178
215
|
|
179
216
|
/*
|
180
217
|
* call-seq:
|
181
|
-
* magic.
|
218
|
+
* magic.close -> nil
|
182
219
|
*
|
183
|
-
*
|
220
|
+
* Closes the underlying _Magic_ database.
|
184
221
|
*
|
185
222
|
* Example:
|
186
223
|
*
|
187
|
-
* magic = Magic.new
|
188
|
-
* magic.
|
224
|
+
* magic = Magic.new
|
225
|
+
* magic.close #=> nil
|
189
226
|
*
|
190
|
-
*
|
227
|
+
* See also: Magic#closed?, Magic#open? and Magic#new
|
191
228
|
*/
|
192
229
|
VALUE
|
193
|
-
|
230
|
+
rb_mgc_close(VALUE object)
|
194
231
|
{
|
195
|
-
|
196
|
-
const char *cstring = NULL;
|
232
|
+
magic_object_t *mo;
|
197
233
|
|
198
|
-
|
234
|
+
if (MAGIC_CLOSED_P(object))
|
235
|
+
return Qnil;
|
199
236
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
237
|
+
MAGIC_OBJECT(mo);
|
238
|
+
if (mo) {
|
239
|
+
MAGIC_SYNCHRONIZED(magic_close_internal, mo);
|
240
|
+
if (DATA_P(object))
|
241
|
+
DATA_PTR(object) = NULL;
|
242
|
+
}
|
204
243
|
|
205
|
-
|
206
|
-
value = magic_split(CSTR2RVAL(cstring), CSTR2RVAL(":"));
|
207
|
-
|
208
|
-
return rb_ivar_set(object, id_at_path, value);
|
244
|
+
return Qnil;
|
209
245
|
}
|
210
246
|
|
211
247
|
/*
|
212
248
|
* call-seq:
|
213
|
-
* magic.
|
249
|
+
* magic.closed? -> true or false
|
214
250
|
*
|
215
|
-
* Returns
|
251
|
+
* Returns +true+ if the underlying _Magic_ database is closed,
|
252
|
+
* or +false+ otherwise.
|
216
253
|
*
|
217
254
|
* Example:
|
218
255
|
*
|
219
|
-
* magic = Magic.new
|
220
|
-
* magic.
|
221
|
-
* magic.
|
222
|
-
* magic.
|
256
|
+
* magic = Magic.new
|
257
|
+
* magic.closed? #=> false
|
258
|
+
* magic.close #=> nil
|
259
|
+
* magic.closed? #=> true
|
223
260
|
*
|
224
|
-
* See also: Magic#
|
261
|
+
* See also: Magic#close, Magic#open? and #Magic#new
|
225
262
|
*/
|
226
263
|
VALUE
|
227
|
-
|
264
|
+
rb_mgc_close_p(VALUE object)
|
228
265
|
{
|
229
|
-
|
230
|
-
|
266
|
+
magic_object_t *mo;
|
267
|
+
magic_t cookie = NULL;
|
268
|
+
|
269
|
+
MAGIC_OBJECT(mo);
|
270
|
+
if (mo)
|
271
|
+
cookie = mo->cookie;
|
272
|
+
|
273
|
+
if (DATA_P(object) && cookie)
|
274
|
+
return Qfalse;
|
275
|
+
|
276
|
+
return Qtrue;
|
231
277
|
}
|
232
278
|
|
233
279
|
/*
|
234
280
|
* call-seq:
|
235
|
-
* magic.
|
281
|
+
* magic.paths -> array
|
236
282
|
*
|
237
283
|
* Example:
|
238
284
|
*
|
239
|
-
* magic = Magic.new
|
240
|
-
* magic.
|
241
|
-
* magic.flags = Magic::MIME_TYPE #=> 16
|
285
|
+
* magic = Magic.new
|
286
|
+
* magic.paths #=> ["/etc/magic", "/usr/share/misc/magic"]
|
242
287
|
*
|
243
|
-
* Will raise <i>Magic::FlagsError</i> exception if, or
|
244
|
-
* <i>Magic::LibraryError</i> exception if, or
|
245
|
-
* <i>Magic::NotImplementedError</i> exception if, or
|
246
288
|
*/
|
247
289
|
VALUE
|
248
|
-
|
290
|
+
rb_mgc_get_paths(VALUE object)
|
249
291
|
{
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
Check_Type(value, T_FIXNUM);
|
292
|
+
const char *cstring = NULL;
|
293
|
+
VALUE value = Qundef;
|
254
294
|
|
255
|
-
|
256
|
-
MAGIC_COOKIE(cookie);
|
295
|
+
MAGIC_CHECK_OPEN(object);
|
257
296
|
|
258
|
-
|
259
|
-
|
297
|
+
value = rb_ivar_get(object, id_at_paths);
|
298
|
+
if (!NIL_P(value) && !RARRAY_EMPTY_P(value) && !getenv("MAGIC"))
|
299
|
+
return value;
|
260
300
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
error(E_FLAG_INVALID_VALUE));
|
265
|
-
break;
|
266
|
-
case ENOSYS:
|
267
|
-
MAGIC_GENERIC_ERROR(rb_mgc_eNotImplementedError, ENOSYS,
|
268
|
-
error(E_FLAG_NOT_IMPLEMENTED));
|
269
|
-
break;
|
270
|
-
default:
|
271
|
-
MAGIC_LIBRARY_ERROR(cookie);
|
272
|
-
break;
|
273
|
-
}
|
274
|
-
}
|
301
|
+
cstring = magic_getpath_wrapper();
|
302
|
+
value = magic_split(CSTR2RVAL(cstring), CSTR2RVAL(":"));
|
303
|
+
RB_GC_GUARD(value);
|
275
304
|
|
276
|
-
|
305
|
+
return value;
|
277
306
|
}
|
278
307
|
|
279
308
|
/*
|
280
309
|
* call-seq:
|
281
|
-
* magic.
|
282
|
-
* magic.load( path, ... ) -> array
|
283
|
-
* magic.load( array ) -> array
|
284
|
-
*
|
285
|
-
* Example:
|
286
|
-
*
|
287
|
-
* magic = Magic.new #=> #<Magic:0x007f8fdc012e58>
|
288
|
-
* magic.load #=> ["/etc/magic", "/usr/share/misc/magic"]
|
289
|
-
* magic.load("/usr/share/misc/magic", "/etc/magic") #=> ["/usr/share/misc/magic", "/etc/magic"]
|
290
|
-
* magic.load #=> ["/etc/magic", "/usr/share/misc/magic"]
|
291
|
-
*
|
292
|
-
* Will raise <i>Magic::LibraryError</i> exception if, or
|
310
|
+
* magic.get_parameter( integer ) -> integer
|
293
311
|
*/
|
294
312
|
VALUE
|
295
|
-
|
313
|
+
rb_mgc_get_parameter(VALUE object, VALUE tag)
|
296
314
|
{
|
297
|
-
|
298
|
-
|
315
|
+
int local_errno;
|
316
|
+
magic_object_t *mo;
|
317
|
+
magic_arguments_t ma;
|
299
318
|
|
300
|
-
|
301
|
-
|
319
|
+
MAGIC_CHECK_INTEGER_TYPE(tag);
|
320
|
+
MAGIC_CHECK_OPEN(object);
|
321
|
+
MAGIC_COOKIE(mo, ma.cookie);
|
302
322
|
|
303
|
-
|
304
|
-
value = magic_join(arguments, CSTR2RVAL(":"));
|
305
|
-
ma.data.file.path = RVAL2CSTR(value);
|
306
|
-
}
|
307
|
-
else {
|
308
|
-
ma.data.file.path = magic_getpath_wrapper();
|
309
|
-
}
|
323
|
+
ma.type.parameter.tag = NUM2INT(tag);
|
310
324
|
|
311
|
-
|
325
|
+
MAGIC_SYNCHRONIZED(magic_get_parameter_internal, &ma);
|
326
|
+
local_errno = errno;
|
312
327
|
|
313
|
-
|
314
|
-
|
315
|
-
|
328
|
+
if (ma.status < 0) {
|
329
|
+
if (local_errno == EINVAL)
|
330
|
+
MAGIC_GENERIC_ERROR(rb_mgc_eParameterError,
|
331
|
+
local_errno,
|
332
|
+
E_PARAM_INVALID_TYPE);
|
316
333
|
|
317
|
-
|
334
|
+
MAGIC_LIBRARY_ERROR(ma.cookie);
|
335
|
+
}
|
318
336
|
|
319
|
-
|
337
|
+
return SIZET2NUM(ma.type.parameter.value);
|
320
338
|
}
|
321
339
|
|
322
340
|
/*
|
323
341
|
* call-seq:
|
324
|
-
* magic.
|
325
|
-
|
326
|
-
|
342
|
+
* magic.set_parameter( integer, integer ) -> nil
|
343
|
+
*/
|
344
|
+
VALUE
|
345
|
+
rb_mgc_set_parameter(VALUE object, VALUE tag, VALUE value)
|
346
|
+
{
|
347
|
+
int local_errno;
|
348
|
+
magic_object_t *mo;
|
349
|
+
magic_arguments_t ma;
|
350
|
+
|
351
|
+
MAGIC_CHECK_INTEGER_TYPE(tag);
|
352
|
+
MAGIC_CHECK_INTEGER_TYPE(value);
|
353
|
+
MAGIC_CHECK_OPEN(object);
|
354
|
+
MAGIC_COOKIE(mo, ma.cookie);
|
355
|
+
|
356
|
+
ma.type.parameter.tag = NUM2INT(tag);
|
357
|
+
ma.type.parameter.value = NUM2SIZET(value);
|
358
|
+
|
359
|
+
MAGIC_SYNCHRONIZED(magic_set_parameter_internal, &ma);
|
360
|
+
local_errno = errno;
|
361
|
+
|
362
|
+
if (ma.status < 0) {
|
363
|
+
switch (local_errno) {
|
364
|
+
case EINVAL:
|
365
|
+
MAGIC_GENERIC_ERROR(rb_mgc_eParameterError,
|
366
|
+
local_errno,
|
367
|
+
E_PARAM_INVALID_TYPE);
|
368
|
+
case EOVERFLOW:
|
369
|
+
MAGIC_GENERIC_ERROR(rb_mgc_eParameterError,
|
370
|
+
local_errno,
|
371
|
+
E_PARAM_INVALID_VALUE);
|
372
|
+
}
|
373
|
+
MAGIC_LIBRARY_ERROR(ma.cookie);
|
374
|
+
}
|
375
|
+
|
376
|
+
return Qnil;
|
377
|
+
}
|
378
|
+
|
379
|
+
/*
|
380
|
+
* call-seq:
|
381
|
+
* magic.flags -> integer
|
327
382
|
*
|
328
383
|
* Example:
|
329
384
|
*
|
330
|
-
* magic = Magic.new
|
385
|
+
* magic = Magic.new
|
386
|
+
* magic.flags #=> 0
|
387
|
+
* magic.flags = Magic::MIME #=> 1040
|
388
|
+
* magic.flags #=> 1040
|
331
389
|
*
|
332
|
-
* See also: Magic#
|
333
|
-
*
|
334
|
-
* Will raise <i>Magic::LibraryError</i> exception if, or
|
390
|
+
* See also: Magic#flags_to_a
|
335
391
|
*/
|
336
392
|
VALUE
|
337
|
-
|
393
|
+
rb_mgc_get_flags(VALUE object)
|
338
394
|
{
|
339
|
-
|
340
|
-
|
395
|
+
int local_errno;
|
396
|
+
magic_object_t *mo;
|
397
|
+
magic_arguments_t ma;
|
341
398
|
|
342
|
-
|
343
|
-
|
399
|
+
MAGIC_CHECK_OPEN(object);
|
400
|
+
MAGIC_COOKIE(mo, ma.cookie);
|
344
401
|
|
345
|
-
|
346
|
-
|
347
|
-
}
|
348
|
-
else {
|
349
|
-
value = magic_join(rb_mgc_get_path(object), CSTR2RVAL(":"));
|
350
|
-
}
|
402
|
+
MAGIC_SYNCHRONIZED(magic_get_flags_internal, &ma);
|
403
|
+
local_errno = errno;
|
351
404
|
|
352
|
-
|
353
|
-
|
405
|
+
if (ma.flags < 0 && local_errno == ENOSYS)
|
406
|
+
return rb_ivar_get(object, id_at_flags);
|
354
407
|
|
355
|
-
|
356
|
-
MAGIC_LIBRARY_ERROR(ma.cookie);
|
357
|
-
}
|
358
|
-
|
359
|
-
return Qtrue;
|
408
|
+
return INT2NUM(ma.flags);
|
360
409
|
}
|
361
410
|
|
362
411
|
/*
|
363
412
|
* call-seq:
|
364
|
-
* magic.
|
365
|
-
* magic.check( path, ... ) -> true or false
|
366
|
-
* magic.check( array ) -> true or false
|
413
|
+
* magic.flags= ( integer ) -> integer
|
367
414
|
*
|
368
415
|
* Example:
|
369
416
|
*
|
370
|
-
* magic = Magic.new
|
417
|
+
* magic = Magic.new
|
418
|
+
* magic.flags = Magic::MIME #=> 1040
|
419
|
+
* magic.flags = Magic::MIME_TYPE #=> 16
|
420
|
+
*/
|
421
|
+
VALUE
|
422
|
+
rb_mgc_set_flags(VALUE object, VALUE value)
|
423
|
+
{
|
424
|
+
int local_errno;
|
425
|
+
magic_object_t *mo;
|
426
|
+
magic_arguments_t ma;
|
427
|
+
|
428
|
+
MAGIC_CHECK_INTEGER_TYPE(value);
|
429
|
+
MAGIC_CHECK_OPEN(object);
|
430
|
+
MAGIC_COOKIE(mo, ma.cookie);
|
431
|
+
|
432
|
+
ma.flags = NUM2INT(value);
|
433
|
+
|
434
|
+
MAGIC_SYNCHRONIZED(magic_set_flags_internal, &ma);
|
435
|
+
local_errno = errno;
|
436
|
+
|
437
|
+
if (ma.status < 0) {
|
438
|
+
switch (local_errno) {
|
439
|
+
case EINVAL:
|
440
|
+
MAGIC_GENERIC_ERROR(rb_mgc_eFlagsError,
|
441
|
+
local_errno,
|
442
|
+
E_FLAG_INVALID_TYPE);
|
443
|
+
case ENOSYS:
|
444
|
+
MAGIC_GENERIC_ERROR(rb_mgc_eNotImplementedError,
|
445
|
+
local_errno,
|
446
|
+
E_FLAG_NOT_IMPLEMENTED);
|
447
|
+
}
|
448
|
+
MAGIC_LIBRARY_ERROR(ma.cookie);
|
449
|
+
}
|
450
|
+
|
451
|
+
return rb_ivar_set(object, id_at_flags, INT2NUM(ma.flags));
|
452
|
+
}
|
453
|
+
|
454
|
+
/*
|
455
|
+
* call-seq:
|
456
|
+
* magic.load -> nil
|
457
|
+
* magic.load( string, ... ) -> nil
|
458
|
+
* magic.load( array ) -> nil
|
371
459
|
*
|
372
|
-
*
|
460
|
+
* Example:
|
373
461
|
*
|
374
|
-
*
|
462
|
+
* See also: Magic#check, Magic#compile, Magic::check and Magic::compile
|
375
463
|
*/
|
376
464
|
VALUE
|
377
|
-
|
465
|
+
rb_mgc_load(VALUE object, VALUE arguments)
|
378
466
|
{
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
467
|
+
magic_object_t *mo;
|
468
|
+
magic_arguments_t ma;
|
469
|
+
const char *klass = "Magic";
|
470
|
+
VALUE value = Qundef;
|
471
|
+
|
472
|
+
if (ARRAY_P(RARRAY_FIRST(arguments)))
|
473
|
+
arguments = magic_flatten(arguments);
|
474
|
+
|
475
|
+
MAGIC_CHECK_ARRAY_OF_STRINGS(arguments);
|
476
|
+
MAGIC_CHECK_OPEN(object);
|
477
|
+
MAGIC_COOKIE(mo, ma.cookie);
|
478
|
+
|
479
|
+
if (rb_mgc_do_not_auto_load) {
|
480
|
+
if (!NIL_P(object))
|
481
|
+
klass = rb_obj_classname(object);
|
482
|
+
|
483
|
+
MAGIC_WARNING(2, "%s::do_not_auto_load is set; using %s#load "
|
484
|
+
"will load Magic database from a file",
|
485
|
+
klass, klass);
|
486
|
+
}
|
487
|
+
|
488
|
+
ma.flags = magic_get_flags(object);
|
489
|
+
|
490
|
+
if (!RARRAY_EMPTY_P(arguments)) {
|
491
|
+
value = magic_join(arguments, CSTR2RVAL(":"));
|
492
|
+
ma.type.file.path = RVAL2CSTR(value);
|
493
|
+
}
|
494
|
+
else
|
495
|
+
ma.type.file.path = magic_getpath_wrapper();
|
496
|
+
|
497
|
+
magic_set_paths(object, RARRAY_EMPTY);
|
498
|
+
|
499
|
+
MAGIC_SYNCHRONIZED(magic_load_internal, &ma);
|
500
|
+
if (ma.status < 0) {
|
501
|
+
mo->database_loaded = 0;
|
502
|
+
MAGIC_LIBRARY_ERROR(ma.cookie);
|
503
|
+
}
|
504
|
+
mo->database_loaded = 1;
|
505
|
+
|
506
|
+
value = magic_split(CSTR2RVAL(ma.type.file.path), CSTR2RVAL(":"));
|
507
|
+
magic_set_paths(object, value);
|
508
|
+
RB_GC_GUARD(value);
|
509
|
+
|
510
|
+
return Qnil;
|
511
|
+
}
|
398
512
|
|
399
|
-
|
513
|
+
/*
|
514
|
+
* call-seq:
|
515
|
+
* magic.load_buffers( string, ... ) -> nil
|
516
|
+
* magic.load_buffers( array ) -> nil
|
517
|
+
*
|
518
|
+
* See also: Magic#load and Magic::do_not_auto_load
|
519
|
+
*/
|
520
|
+
VALUE
|
521
|
+
rb_mgc_load_buffers(VALUE object, VALUE arguments)
|
522
|
+
{
|
523
|
+
size_t count;
|
524
|
+
int local_errno;
|
525
|
+
magic_object_t *mo;
|
526
|
+
magic_arguments_t ma;
|
527
|
+
void **pointers = NULL;
|
528
|
+
size_t *sizes = NULL;
|
529
|
+
VALUE value = Qundef;
|
530
|
+
|
531
|
+
count = (size_t)RARRAY_LEN(arguments);
|
532
|
+
MAGIC_CHECK_ARGUMENT_MISSING(count, 1);
|
533
|
+
|
534
|
+
if (ARRAY_P(RARRAY_FIRST(arguments))) {
|
535
|
+
arguments = magic_flatten(arguments);
|
536
|
+
count = (size_t)RARRAY_LEN(arguments);
|
537
|
+
}
|
538
|
+
|
539
|
+
MAGIC_CHECK_ARRAY_EMPTY(arguments);
|
540
|
+
MAGIC_CHECK_ARRAY_OF_STRINGS(arguments);
|
541
|
+
MAGIC_CHECK_OPEN(object);
|
542
|
+
MAGIC_COOKIE(mo, ma.cookie);
|
543
|
+
|
544
|
+
pointers = ALLOC_N(void *, count);
|
545
|
+
if (!pointers) {
|
546
|
+
local_errno = ENOMEM;
|
547
|
+
goto error;
|
548
|
+
}
|
549
|
+
|
550
|
+
sizes = ALLOC_N(size_t, count);
|
551
|
+
if (!sizes) {
|
552
|
+
ruby_xfree(pointers);
|
553
|
+
local_errno = ENOMEM;
|
554
|
+
goto error;
|
555
|
+
}
|
556
|
+
|
557
|
+
for (size_t i = 0; i < count; i++) {
|
558
|
+
value = RARRAY_AREF(arguments, (long)i);
|
559
|
+
pointers[i] = (void *)RSTRING_PTR(value);
|
560
|
+
sizes[i] = (size_t)RSTRING_LEN(value);
|
561
|
+
}
|
562
|
+
|
563
|
+
ma.flags = magic_get_flags(object);
|
564
|
+
ma.type.buffers.count = count;
|
565
|
+
ma.type.buffers.pointers = pointers;
|
566
|
+
ma.type.buffers.sizes = sizes;
|
567
|
+
|
568
|
+
magic_set_paths(object, RARRAY_EMPTY);
|
569
|
+
|
570
|
+
MAGIC_SYNCHRONIZED(magic_load_buffers_internal, &ma);
|
571
|
+
if (ma.status < 0) {
|
572
|
+
local_errno = errno;
|
573
|
+
ruby_xfree(pointers);
|
574
|
+
ruby_xfree(sizes);
|
575
|
+
goto error;
|
576
|
+
}
|
577
|
+
mo->database_loaded = 1;
|
578
|
+
|
579
|
+
ruby_xfree(pointers);
|
580
|
+
ruby_xfree(sizes);
|
581
|
+
|
582
|
+
return Qnil;
|
583
|
+
error:
|
584
|
+
mo->database_loaded = 0;
|
585
|
+
|
586
|
+
if (local_errno == ENOMEM)
|
587
|
+
MAGIC_GENERIC_ERROR(rb_mgc_eLibraryError,
|
588
|
+
local_errno,
|
589
|
+
E_NOT_ENOUGH_MEMORY);
|
590
|
+
|
591
|
+
MAGIC_LIBRARY_ERROR(ma.cookie);
|
400
592
|
}
|
401
593
|
|
402
594
|
/*
|
403
595
|
* call-seq:
|
404
|
-
* magic.
|
596
|
+
* magic.loaded? -> true or false
|
405
597
|
*
|
406
|
-
* Returns
|
598
|
+
* Returns +true+ if at least a single Magic database file had been loaded, or
|
599
|
+
* +false+ otherwise. Magic database files can be loaded from a file or from an
|
600
|
+
* in-memory buffer.
|
407
601
|
*
|
408
602
|
* Example:
|
409
603
|
*
|
410
|
-
* magic = Magic.new
|
604
|
+
* magic = Magic.new
|
605
|
+
* magic.loaded? #=> true
|
411
606
|
*
|
412
|
-
*
|
607
|
+
* Example:
|
413
608
|
*
|
414
|
-
*
|
609
|
+
* Magic.do_not_auto_load = true #=> true
|
610
|
+
* magic = Magic.new
|
611
|
+
* magic.loaded? #=> false
|
612
|
+
*
|
613
|
+
* See also: Magic#load and Magic#load_buffers
|
415
614
|
*/
|
416
615
|
VALUE
|
417
|
-
|
616
|
+
rb_mgc_load_p(VALUE object)
|
418
617
|
{
|
419
|
-
|
420
|
-
magic_arguments_t ma;
|
421
|
-
const char *cstring = NULL;
|
422
|
-
const char *empty = "(null)";
|
618
|
+
magic_object_t *mo;
|
423
619
|
|
424
|
-
|
620
|
+
MAGIC_CHECK_OPEN(object);
|
621
|
+
MAGIC_OBJECT(mo);
|
425
622
|
|
426
|
-
|
427
|
-
|
623
|
+
return CBOOL2RVAL(mo->database_loaded);
|
624
|
+
}
|
428
625
|
|
429
|
-
|
430
|
-
|
626
|
+
/*
|
627
|
+
* call-seq:
|
628
|
+
* magic.compile( string ) -> nil
|
629
|
+
* magic.compile( array ) -> nil
|
630
|
+
*
|
631
|
+
* See also: Magic#check, Magic::check and Magic::compile
|
632
|
+
*/
|
633
|
+
VALUE
|
634
|
+
rb_mgc_compile(VALUE object, VALUE value)
|
635
|
+
{
|
636
|
+
magic_object_t *mo;
|
637
|
+
magic_arguments_t ma;
|
431
638
|
|
432
|
-
|
433
|
-
|
434
|
-
|
639
|
+
MAGIC_CHECK_STRING_TYPE(value);
|
640
|
+
MAGIC_CHECK_OPEN(object);
|
641
|
+
MAGIC_COOKIE(mo, ma.cookie);
|
435
642
|
|
436
|
-
|
437
|
-
|
438
|
-
}
|
439
|
-
else if (rv < 515) {
|
440
|
-
(void)magic_errno(ma.cookie);
|
441
|
-
cstring = magic_error(ma.cookie);
|
442
|
-
}
|
443
|
-
}
|
643
|
+
ma.flags = magic_get_flags(object);
|
644
|
+
ma.type.file.path = RVAL2CSTR(value);
|
444
645
|
|
445
|
-
|
446
|
-
|
447
|
-
|
646
|
+
MAGIC_SYNCHRONIZED(magic_compile_internal, &ma);
|
647
|
+
if (ma.status < 0)
|
648
|
+
MAGIC_LIBRARY_ERROR(ma.cookie);
|
448
649
|
|
449
|
-
|
650
|
+
return Qnil;
|
450
651
|
}
|
451
652
|
|
452
653
|
/*
|
453
654
|
* call-seq:
|
454
|
-
* magic.
|
455
|
-
*
|
456
|
-
* Returns
|
655
|
+
* magic.check( string ) -> true or false
|
656
|
+
* magic.check( array ) -> true or false
|
457
657
|
*
|
458
|
-
*
|
459
|
-
|
460
|
-
|
658
|
+
* See also: Magic#compile, Magic::compile and Magic::check
|
659
|
+
*/
|
660
|
+
VALUE
|
661
|
+
rb_mgc_check(VALUE object, VALUE value)
|
662
|
+
{
|
663
|
+
magic_object_t *mo;
|
664
|
+
magic_arguments_t ma;
|
665
|
+
|
666
|
+
MAGIC_CHECK_STRING_TYPE(value);
|
667
|
+
MAGIC_CHECK_OPEN(object);
|
668
|
+
MAGIC_COOKIE(mo, ma.cookie);
|
669
|
+
|
670
|
+
ma.flags = magic_get_flags(object);
|
671
|
+
ma.type.file.path = RVAL2CSTR(value);
|
672
|
+
|
673
|
+
MAGIC_SYNCHRONIZED(magic_check_internal, &ma);
|
674
|
+
return ma.status < 0 ? Qfalse : Qtrue;
|
675
|
+
}
|
676
|
+
|
677
|
+
/*
|
678
|
+
* call-seq:
|
679
|
+
* magic.file( object ) -> string or array
|
680
|
+
* magic.file( string ) -> string or array
|
461
681
|
*
|
462
|
-
*
|
682
|
+
* See also: Magic#buffer and Magic#descriptor
|
683
|
+
*/
|
684
|
+
VALUE
|
685
|
+
rb_mgc_file(VALUE object, VALUE value)
|
686
|
+
{
|
687
|
+
magic_object_t *mo;
|
688
|
+
magic_arguments_t ma;
|
689
|
+
const char *empty = "(null)";
|
690
|
+
|
691
|
+
UNUSED(empty);
|
692
|
+
|
693
|
+
if (NIL_P(value))
|
694
|
+
goto error;
|
695
|
+
|
696
|
+
MAGIC_CHECK_OPEN(object);
|
697
|
+
MAGIC_CHECK_LOADED(object);
|
698
|
+
MAGIC_COOKIE(mo, ma.cookie);
|
699
|
+
|
700
|
+
if (rb_respond_to(value, rb_intern("to_io")))
|
701
|
+
return rb_mgc_descriptor(object, value);
|
702
|
+
|
703
|
+
value = magic_path(value);
|
704
|
+
if (NIL_P(value))
|
705
|
+
goto error;
|
706
|
+
|
707
|
+
ma.stop_on_errors = mo->stop_on_errors;
|
708
|
+
ma.flags = magic_get_flags(object);
|
709
|
+
ma.type.file.path = RVAL2CSTR(value);
|
710
|
+
|
711
|
+
MAGIC_SYNCHRONIZED(magic_file_internal, &ma);
|
712
|
+
if (ma.status < 0 && !ma.result) {
|
713
|
+
/*
|
714
|
+
* Handle the case when the "ERROR" flag is set regardless of the
|
715
|
+
* current version of the underlying Magic library.
|
716
|
+
*
|
717
|
+
* Prior to version 5.15 the correct behavior that concerns the
|
718
|
+
* following IEEE 1003.1 standards was broken:
|
719
|
+
*
|
720
|
+
* http://pubs.opengroup.org/onlinepubs/007904975/utilities/file.html
|
721
|
+
* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/file.html
|
722
|
+
*
|
723
|
+
* This is an attempt to mitigate the problem and correct it to achieve
|
724
|
+
* the desired behavior as per the standards.
|
725
|
+
*/
|
726
|
+
if (mo->stop_on_errors || (ma.flags & MAGIC_ERROR))
|
727
|
+
MAGIC_LIBRARY_ERROR(ma.cookie);
|
728
|
+
|
729
|
+
ma.result = magic_error_wrapper(ma.cookie);
|
730
|
+
}
|
731
|
+
if (!ma.result)
|
732
|
+
MAGIC_GENERIC_ERROR(rb_mgc_eMagicError, EINVAL, E_UNKNOWN);
|
733
|
+
|
734
|
+
assert(ma.result != NULL && \
|
735
|
+
"Must be a valid pointer to `const char' type");
|
736
|
+
|
737
|
+
/*
|
738
|
+
* Depending on the version of the underlying Magic library the magic_file()
|
739
|
+
* function can fail and either yield no results or return the "(null)"
|
740
|
+
* string instead. Often this would indicate that an older version of the
|
741
|
+
* Magic library is in use.
|
742
|
+
*/
|
743
|
+
assert(strncmp(ma.result, empty, strlen(empty)) != 0 && \
|
744
|
+
"Empty or invalid result");
|
745
|
+
|
746
|
+
return magic_return(&ma);
|
747
|
+
error:
|
748
|
+
MAGIC_ARGUMENT_TYPE_ERROR(value, "String or IO-like object");
|
749
|
+
}
|
750
|
+
|
751
|
+
/*
|
752
|
+
* call-seq:
|
753
|
+
* magic.buffer( string ) -> string or array
|
463
754
|
*
|
464
755
|
* See also: Magic#file and Magic#descriptor
|
465
756
|
*/
|
466
757
|
VALUE
|
467
758
|
rb_mgc_buffer(VALUE object, VALUE value)
|
468
759
|
{
|
469
|
-
|
470
|
-
|
760
|
+
magic_object_t *mo;
|
761
|
+
magic_arguments_t ma;
|
471
762
|
|
472
|
-
|
763
|
+
MAGIC_CHECK_STRING_TYPE(value);
|
764
|
+
MAGIC_CHECK_OPEN(object);
|
765
|
+
MAGIC_CHECK_LOADED(object);
|
766
|
+
MAGIC_COOKIE(mo, ma.cookie);
|
473
767
|
|
474
|
-
|
475
|
-
MAGIC_COOKIE(ma.cookie);
|
768
|
+
StringValue(value);
|
476
769
|
|
477
|
-
|
770
|
+
ma.flags = magic_get_flags(object);
|
771
|
+
ma.type.buffers.pointers = (void **)RSTRING_PTR(value);
|
772
|
+
ma.type.buffers.sizes = (size_t *)RSTRING_LEN(value);
|
478
773
|
|
479
|
-
|
480
|
-
|
774
|
+
MAGIC_SYNCHRONIZED(magic_buffer_internal, &ma);
|
775
|
+
if (ma.status < 0)
|
776
|
+
MAGIC_LIBRARY_ERROR(ma.cookie);
|
481
777
|
|
482
|
-
|
483
|
-
|
484
|
-
MAGIC_LIBRARY_ERROR(ma.cookie);
|
485
|
-
}
|
778
|
+
assert(ma.result != NULL && \
|
779
|
+
"Must be a valid pointer to `const char' type");
|
486
780
|
|
487
|
-
|
781
|
+
return magic_return(&ma);
|
488
782
|
}
|
489
783
|
|
490
784
|
/*
|
491
785
|
* call-seq:
|
786
|
+
* magic.descriptor( object ) -> string or array
|
492
787
|
* magic.descriptor( integer ) -> string or array
|
493
788
|
*
|
494
|
-
* Returns
|
495
|
-
*
|
496
|
-
* Example:
|
497
|
-
*
|
498
|
-
* magic = Magic.new #=> #<Magic:0x007f8fdc012e58>
|
499
|
-
*
|
500
|
-
* Will raise <i>Magic::LibraryError</i> exception if, or
|
501
|
-
*
|
502
789
|
* See also: Magic#file and Magic#buffer
|
503
790
|
*/
|
504
791
|
VALUE
|
505
792
|
rb_mgc_descriptor(VALUE object, VALUE value)
|
506
793
|
{
|
507
|
-
|
508
|
-
|
794
|
+
int local_errno;
|
795
|
+
magic_object_t *mo;
|
796
|
+
magic_arguments_t ma;
|
797
|
+
|
798
|
+
if (rb_respond_to(value, rb_intern("to_io")))
|
799
|
+
value = INT2NUM(magic_fileno(value));
|
800
|
+
|
801
|
+
MAGIC_CHECK_INTEGER_TYPE(value);
|
802
|
+
MAGIC_CHECK_OPEN(object);
|
803
|
+
MAGIC_CHECK_LOADED(object);
|
804
|
+
MAGIC_COOKIE(mo, ma.cookie);
|
509
805
|
|
510
|
-
|
806
|
+
ma.flags = magic_get_flags(object);
|
807
|
+
ma.type.file.fd = NUM2INT(value);
|
511
808
|
|
512
|
-
|
513
|
-
|
809
|
+
MAGIC_SYNCHRONIZED(magic_descriptor_internal, &ma);
|
810
|
+
local_errno = errno;
|
514
811
|
|
515
|
-
|
516
|
-
|
812
|
+
if (ma.status < 0) {
|
813
|
+
if (local_errno == EBADF)
|
814
|
+
rb_raise(rb_eIOError, "Bad file descriptor");
|
517
815
|
|
518
|
-
|
519
|
-
|
520
|
-
MAGIC_LIBRARY_ERROR(ma.cookie);
|
521
|
-
}
|
816
|
+
MAGIC_LIBRARY_ERROR(ma.cookie);
|
817
|
+
}
|
522
818
|
|
523
|
-
|
819
|
+
assert(ma.result != NULL && \
|
820
|
+
"Must be a valid pointer to `const char' type");
|
821
|
+
|
822
|
+
return magic_return(&ma);
|
524
823
|
}
|
525
824
|
|
526
825
|
/*
|
527
826
|
* call-seq:
|
528
827
|
* Magic.version -> integer
|
529
828
|
*
|
530
|
-
* Returns
|
531
|
-
*
|
532
829
|
* Example:
|
533
830
|
*
|
534
|
-
* Magic.version
|
535
|
-
*
|
536
|
-
* Will raise <i>Magic::NotImplementedError</i> exception if, or
|
831
|
+
* Magic.version #=> 517
|
537
832
|
*
|
538
833
|
* See also: Magic::version_to_a and Magic::version_to_s
|
539
834
|
*/
|
540
835
|
VALUE
|
541
|
-
rb_mgc_version(VALUE object)
|
836
|
+
rb_mgc_version(RB_UNUSED_VAR(VALUE object))
|
542
837
|
{
|
543
|
-
|
544
|
-
int local_errno;
|
545
|
-
|
546
|
-
UNUSED(object);
|
547
|
-
|
548
|
-
rv = magic_version_wrapper();
|
549
|
-
local_errno = errno;
|
550
|
-
|
551
|
-
if (rv < 0 && local_errno == ENOSYS) {
|
552
|
-
MAGIC_GENERIC_ERROR(rb_mgc_eNotImplementedError, ENOSYS,
|
553
|
-
error(E_NOT_IMPLEMENTED));
|
554
|
-
}
|
555
|
-
|
556
|
-
return INT2NUM(rv);
|
838
|
+
return INT2NUM(magic_version_wrapper());
|
557
839
|
}
|
558
840
|
|
559
|
-
/* :enddoc: */
|
560
|
-
|
561
841
|
static inline void*
|
562
842
|
nogvl_magic_load(void *data)
|
563
843
|
{
|
564
|
-
|
565
|
-
magic_arguments_t *ma = data;
|
844
|
+
magic_arguments_t *ma = data;
|
566
845
|
|
567
|
-
|
568
|
-
|
846
|
+
ma->status = magic_load_wrapper(ma->cookie,
|
847
|
+
ma->type.file.path,
|
848
|
+
ma->flags);
|
849
|
+
return NULL;
|
569
850
|
}
|
570
851
|
|
571
852
|
static inline void*
|
572
853
|
nogvl_magic_compile(void *data)
|
573
854
|
{
|
574
|
-
|
575
|
-
magic_arguments_t *ma = data;
|
855
|
+
magic_arguments_t *ma = data;
|
576
856
|
|
577
|
-
|
578
|
-
|
857
|
+
ma->status = magic_compile_wrapper(ma->cookie,
|
858
|
+
ma->type.file.path,
|
859
|
+
ma->flags);
|
860
|
+
return NULL;
|
579
861
|
}
|
580
862
|
|
581
863
|
static inline void*
|
582
864
|
nogvl_magic_check(void *data)
|
583
865
|
{
|
584
|
-
|
585
|
-
magic_arguments_t *ma = data;
|
866
|
+
magic_arguments_t *ma = data;
|
586
867
|
|
587
|
-
|
588
|
-
|
868
|
+
ma->status = magic_check_wrapper(ma->cookie,
|
869
|
+
ma->type.file.path,
|
870
|
+
ma->flags);
|
871
|
+
return NULL;
|
589
872
|
}
|
590
873
|
|
591
874
|
static inline void*
|
592
875
|
nogvl_magic_file(void *data)
|
593
876
|
{
|
594
|
-
|
595
|
-
|
877
|
+
magic_arguments_t *ma = data;
|
878
|
+
|
879
|
+
ma->result = magic_file_wrapper(ma->cookie,
|
880
|
+
ma->type.file.path,
|
881
|
+
ma->flags);
|
882
|
+
|
883
|
+
ma->status = !ma->result ? -1 : 0;
|
884
|
+
return NULL;
|
596
885
|
}
|
597
886
|
|
598
887
|
static inline void*
|
599
888
|
nogvl_magic_descriptor(void *data)
|
600
889
|
{
|
601
|
-
|
602
|
-
|
890
|
+
magic_arguments_t *ma = data;
|
891
|
+
|
892
|
+
ma->result = magic_descriptor_wrapper(ma->cookie,
|
893
|
+
ma->type.file.fd,
|
894
|
+
ma->flags);
|
895
|
+
|
896
|
+
ma->status = !ma->result ? -1 : 0;
|
897
|
+
return NULL;
|
898
|
+
}
|
899
|
+
|
900
|
+
static inline VALUE
|
901
|
+
magic_get_parameter_internal(void *data)
|
902
|
+
{
|
903
|
+
size_t value;
|
904
|
+
magic_arguments_t *ma = data;
|
905
|
+
|
906
|
+
ma->status = magic_getparam_wrapper(ma->cookie,
|
907
|
+
ma->type.parameter.tag,
|
908
|
+
&value);
|
909
|
+
ma->type.parameter.value = value;
|
910
|
+
return (VALUE)NULL;
|
911
|
+
}
|
912
|
+
|
913
|
+
static inline VALUE
|
914
|
+
magic_set_parameter_internal(void *data)
|
915
|
+
{
|
916
|
+
size_t value;
|
917
|
+
magic_arguments_t *ma = data;
|
918
|
+
|
919
|
+
value = ma->type.parameter.value;
|
920
|
+
ma->status = magic_setparam_wrapper(ma->cookie,
|
921
|
+
ma->type.parameter.tag,
|
922
|
+
&value);
|
923
|
+
return (VALUE)NULL;
|
924
|
+
}
|
925
|
+
|
926
|
+
static inline VALUE
|
927
|
+
magic_get_flags_internal(void *data)
|
928
|
+
{
|
929
|
+
magic_arguments_t *ma = data;
|
930
|
+
|
931
|
+
ma->flags = magic_getflags_wrapper(ma->cookie);
|
932
|
+
return (VALUE)NULL;
|
933
|
+
}
|
934
|
+
|
935
|
+
static inline VALUE
|
936
|
+
magic_set_flags_internal(void *data)
|
937
|
+
{
|
938
|
+
magic_arguments_t *ma = data;
|
939
|
+
|
940
|
+
ma->status = magic_setflags_wrapper(ma->cookie, ma->flags);
|
941
|
+
return (VALUE)NULL;
|
603
942
|
}
|
604
943
|
|
605
944
|
static inline VALUE
|
606
945
|
magic_close_internal(void *data)
|
607
946
|
{
|
608
|
-
|
609
|
-
|
947
|
+
magic_library_close(data);
|
948
|
+
return Qnil;
|
610
949
|
}
|
611
950
|
|
612
951
|
static inline VALUE
|
613
952
|
magic_load_internal(void *data)
|
614
953
|
{
|
615
|
-
|
954
|
+
magic_arguments_t *ma = data;
|
955
|
+
int old_flags = ma->flags;
|
956
|
+
|
957
|
+
NOGVL(nogvl_magic_load, ma);
|
958
|
+
if (MAGIC_STATUS_CHECK(ma->status < 0))
|
959
|
+
magic_setflags_wrapper(ma->cookie, old_flags);
|
960
|
+
|
961
|
+
return (VALUE)NULL;
|
962
|
+
}
|
963
|
+
|
964
|
+
static inline VALUE
|
965
|
+
magic_load_buffers_internal(void *data)
|
966
|
+
{
|
967
|
+
magic_arguments_t *ma = data;
|
968
|
+
|
969
|
+
ma->status = magic_load_buffers_wrapper(ma->cookie,
|
970
|
+
ma->type.buffers.pointers,
|
971
|
+
ma->type.buffers.sizes,
|
972
|
+
ma->type.buffers.count,
|
973
|
+
ma->flags);
|
974
|
+
return (VALUE)NULL;
|
616
975
|
}
|
617
976
|
|
618
977
|
static inline VALUE
|
619
978
|
magic_compile_internal(void *data)
|
620
979
|
{
|
621
|
-
|
980
|
+
magic_arguments_t *ma = data;
|
981
|
+
int old_flags = ma->flags;
|
982
|
+
|
983
|
+
NOGVL(nogvl_magic_compile, ma);
|
984
|
+
if (MAGIC_STATUS_CHECK(ma->status < 0))
|
985
|
+
magic_setflags_wrapper(ma->cookie, old_flags);
|
986
|
+
|
987
|
+
return (VALUE)NULL;
|
622
988
|
}
|
623
989
|
|
624
990
|
static inline VALUE
|
625
991
|
magic_check_internal(void *data)
|
626
992
|
{
|
627
|
-
|
993
|
+
magic_arguments_t *ma = data;
|
994
|
+
int old_flags = ma->flags;
|
995
|
+
|
996
|
+
NOGVL(nogvl_magic_check, ma);
|
997
|
+
if (MAGIC_STATUS_CHECK(ma->status < 0))
|
998
|
+
magic_setflags_wrapper(ma->cookie, old_flags);
|
999
|
+
|
1000
|
+
return (VALUE)NULL;
|
628
1001
|
}
|
629
1002
|
|
630
|
-
static
|
1003
|
+
static VALUE
|
631
1004
|
magic_file_internal(void *data)
|
632
1005
|
{
|
633
|
-
|
1006
|
+
magic_arguments_t *ma = data;
|
1007
|
+
int old_flags = ma->flags;
|
1008
|
+
int restore_flags;
|
1009
|
+
int local_errno;
|
1010
|
+
|
1011
|
+
if (ma->stop_on_errors)
|
1012
|
+
ma->flags |= MAGIC_ERROR;
|
1013
|
+
|
1014
|
+
if (ma->flags & MAGIC_CONTINUE)
|
1015
|
+
ma->flags |= MAGIC_RAW;
|
1016
|
+
|
1017
|
+
restore_flags = old_flags != ma->flags;
|
1018
|
+
|
1019
|
+
if (restore_flags)
|
1020
|
+
magic_setflags_wrapper(ma->cookie, ma->flags);
|
1021
|
+
|
1022
|
+
NOGVL(nogvl_magic_file, ma);
|
1023
|
+
local_errno = errno;
|
1024
|
+
/*
|
1025
|
+
* The Magic library often does not correctly report errors,
|
1026
|
+
* especially when certain flags (such as e.g., MAGIC_EXTENSION,
|
1027
|
+
* etc.) are set. Attempt to obtain an error code first from the
|
1028
|
+
* Magic library itself, and if that does not work, then from
|
1029
|
+
* the saved errno value.
|
1030
|
+
*/
|
1031
|
+
if (magic_errno_wrapper(ma->cookie) || local_errno)
|
1032
|
+
ma->status = -1;
|
1033
|
+
|
1034
|
+
if (restore_flags)
|
1035
|
+
magic_setflags_wrapper(ma->cookie, old_flags);
|
1036
|
+
|
1037
|
+
return (VALUE)NULL;
|
634
1038
|
}
|
635
1039
|
|
636
|
-
static
|
1040
|
+
static VALUE
|
637
1041
|
magic_buffer_internal(void *data)
|
638
1042
|
{
|
639
|
-
|
640
|
-
|
641
|
-
|
1043
|
+
magic_arguments_t *ma = data;
|
1044
|
+
int old_flags = ma->flags;
|
1045
|
+
int restore_flags;
|
1046
|
+
|
1047
|
+
if (ma->flags & MAGIC_CONTINUE)
|
1048
|
+
ma->flags |= MAGIC_RAW;
|
1049
|
+
|
1050
|
+
restore_flags = old_flags != ma->flags;
|
1051
|
+
|
1052
|
+
if (restore_flags)
|
1053
|
+
magic_setflags_wrapper(ma->cookie, ma->flags);
|
1054
|
+
|
1055
|
+
ma->result = magic_buffer_wrapper(ma->cookie,
|
1056
|
+
(const void *)ma->type.buffers.pointers,
|
1057
|
+
(size_t)ma->type.buffers.sizes,
|
1058
|
+
ma->flags);
|
1059
|
+
|
1060
|
+
ma->status = !ma->result ? -1 : 0;
|
1061
|
+
|
1062
|
+
if (restore_flags)
|
1063
|
+
magic_setflags_wrapper(ma->cookie, old_flags);
|
1064
|
+
|
1065
|
+
return (VALUE)NULL;
|
642
1066
|
}
|
643
1067
|
|
644
|
-
static
|
1068
|
+
static VALUE
|
645
1069
|
magic_descriptor_internal(void *data)
|
646
1070
|
{
|
647
|
-
|
1071
|
+
magic_arguments_t *ma = data;
|
1072
|
+
int old_flags = ma->flags;
|
1073
|
+
int restore_flags;
|
1074
|
+
|
1075
|
+
if (ma->flags & MAGIC_CONTINUE)
|
1076
|
+
ma->flags |= MAGIC_RAW;
|
1077
|
+
|
1078
|
+
restore_flags = old_flags != ma->flags;
|
1079
|
+
|
1080
|
+
if (restore_flags)
|
1081
|
+
magic_setflags_wrapper(ma->cookie, ma->flags);
|
1082
|
+
|
1083
|
+
NOGVL(nogvl_magic_descriptor, ma);
|
1084
|
+
|
1085
|
+
if (restore_flags)
|
1086
|
+
magic_setflags_wrapper(ma->cookie, old_flags);
|
1087
|
+
|
1088
|
+
return (VALUE)NULL;
|
1089
|
+
}
|
1090
|
+
|
1091
|
+
static inline void*
|
1092
|
+
magic_library_open(void)
|
1093
|
+
{
|
1094
|
+
magic_t cookie;
|
1095
|
+
|
1096
|
+
cookie = magic_open_wrapper(MAGIC_NONE);
|
1097
|
+
if (!cookie) {
|
1098
|
+
errno = ENOMEM;
|
1099
|
+
return NULL;
|
1100
|
+
}
|
1101
|
+
|
1102
|
+
return cookie;
|
1103
|
+
}
|
1104
|
+
|
1105
|
+
static inline void
|
1106
|
+
magic_library_close(void *data)
|
1107
|
+
{
|
1108
|
+
magic_object_t *mo = data;
|
1109
|
+
|
1110
|
+
assert(mo != NULL && \
|
1111
|
+
"Must be a valid pointer to `magic_object_t' type");
|
1112
|
+
|
1113
|
+
if (mo->cookie)
|
1114
|
+
magic_close_wrapper(mo->cookie);
|
1115
|
+
|
1116
|
+
mo->cookie = NULL;
|
648
1117
|
}
|
649
1118
|
|
650
1119
|
static VALUE
|
651
1120
|
magic_allocate(VALUE klass)
|
652
1121
|
{
|
653
|
-
|
1122
|
+
int local_errno;
|
1123
|
+
magic_object_t *mo;
|
1124
|
+
|
1125
|
+
mo = (magic_object_t *)ruby_xmalloc(sizeof(magic_object_t));
|
1126
|
+
local_errno = ENOMEM;
|
1127
|
+
|
1128
|
+
if (!mo) {
|
1129
|
+
errno = local_errno;
|
1130
|
+
MAGIC_GENERIC_ERROR(rb_mgc_eLibraryError,
|
1131
|
+
local_errno,
|
1132
|
+
E_NOT_ENOUGH_MEMORY);
|
1133
|
+
}
|
1134
|
+
|
1135
|
+
mo->cookie = NULL;
|
1136
|
+
mo->mutex = Qundef;
|
1137
|
+
mo->database_loaded = 0;
|
1138
|
+
mo->stop_on_errors = 0;
|
1139
|
+
|
1140
|
+
mo->cookie = magic_library_open();
|
1141
|
+
local_errno = errno;
|
1142
|
+
|
1143
|
+
if (!mo->cookie) {
|
1144
|
+
ruby_xfree(mo);
|
1145
|
+
mo = NULL;
|
1146
|
+
errno = local_errno;
|
1147
|
+
MAGIC_GENERIC_ERROR(rb_mgc_eLibraryError,
|
1148
|
+
local_errno,
|
1149
|
+
E_MAGIC_LIBRARY_INITIALIZE);
|
1150
|
+
}
|
1151
|
+
|
1152
|
+
return TypedData_Wrap_Struct(klass, &rb_magic_type, mo);
|
1153
|
+
}
|
1154
|
+
|
1155
|
+
static inline void
|
1156
|
+
magic_mark(void *data)
|
1157
|
+
{
|
1158
|
+
magic_object_t *mo = data;
|
654
1159
|
|
655
|
-
|
656
|
-
|
657
|
-
MAGIC_GENERIC_ERROR(rb_mgc_eLibraryError, EPERM,
|
658
|
-
error(E_MAGIC_LIBRARY_INITIALIZE));
|
659
|
-
}
|
1160
|
+
assert(mo != NULL && \
|
1161
|
+
"Must be a valid pointer to `magic_object_t' type");
|
660
1162
|
|
661
|
-
|
1163
|
+
MAGIC_GC_MARK(mo->mutex);
|
662
1164
|
}
|
663
1165
|
|
664
|
-
static void
|
1166
|
+
static inline void
|
665
1167
|
magic_free(void *data)
|
666
1168
|
{
|
667
|
-
|
668
|
-
assert(cookie != NULL && "Must be a valid pointer to `magic_t' type");
|
1169
|
+
magic_object_t *mo = data;
|
669
1170
|
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
1171
|
+
assert(mo != NULL && \
|
1172
|
+
"Must be a valid pointer to `magic_object_t' type");
|
1173
|
+
|
1174
|
+
if (mo->cookie)
|
1175
|
+
magic_library_close(data);
|
1176
|
+
|
1177
|
+
mo->cookie = NULL;
|
1178
|
+
mo->mutex = Qundef;
|
1179
|
+
|
1180
|
+
ruby_xfree(mo);
|
674
1181
|
}
|
675
1182
|
|
676
|
-
static
|
1183
|
+
static inline size_t
|
1184
|
+
magic_size(const void *data)
|
1185
|
+
{
|
1186
|
+
const magic_object_t *mo = data;
|
1187
|
+
|
1188
|
+
assert(mo != NULL && \
|
1189
|
+
"Must be a valid pointer to `magic_object_t' type");
|
1190
|
+
|
1191
|
+
return sizeof(*mo);
|
1192
|
+
}
|
1193
|
+
|
1194
|
+
#if defined(HAVE_RUBY_GC_COMPACT)
|
1195
|
+
static inline void
|
1196
|
+
magic_compact(void *data)
|
1197
|
+
{
|
1198
|
+
magic_object_t *mo = data;
|
1199
|
+
|
1200
|
+
assert(mo != NULL && \
|
1201
|
+
"Must be a valid pointer to `magic_object_t' type");
|
1202
|
+
|
1203
|
+
mo->mutex = rb_gc_location(mo->mutex);
|
1204
|
+
}
|
1205
|
+
#endif /* HAVE_RUBY_GC_COMPACT */
|
1206
|
+
|
1207
|
+
static inline VALUE
|
677
1208
|
magic_exception_wrapper(VALUE value)
|
678
1209
|
{
|
679
|
-
|
680
|
-
|
1210
|
+
magic_exception_t *e = (struct magic_exception *)value;
|
1211
|
+
|
1212
|
+
return rb_exc_new2(e->klass, e->magic_error);
|
681
1213
|
}
|
682
1214
|
|
683
1215
|
static VALUE
|
684
1216
|
magic_exception(void *data)
|
685
1217
|
{
|
686
|
-
|
687
|
-
|
1218
|
+
magic_exception_t *e = data;
|
1219
|
+
int exception = 0;
|
1220
|
+
VALUE object = Qundef;
|
688
1221
|
|
689
|
-
|
690
|
-
|
1222
|
+
assert(e != NULL && \
|
1223
|
+
"Must be a valid pointer to `magic_exception_t' type");
|
691
1224
|
|
692
|
-
|
1225
|
+
object = rb_protect(magic_exception_wrapper, (VALUE)e, &exception);
|
693
1226
|
|
694
|
-
|
695
|
-
|
696
|
-
}
|
1227
|
+
if (exception)
|
1228
|
+
rb_jump_tag(exception);
|
697
1229
|
|
698
|
-
|
1230
|
+
rb_iv_set(object, "@errno", INT2NUM(e->magic_errno));
|
1231
|
+
RB_GC_GUARD(object);
|
699
1232
|
|
700
|
-
|
1233
|
+
return object;
|
701
1234
|
}
|
702
1235
|
|
703
|
-
static VALUE
|
1236
|
+
static inline VALUE
|
704
1237
|
magic_generic_error(VALUE klass, int magic_errno, const char *magic_error)
|
705
1238
|
{
|
706
|
-
|
1239
|
+
magic_exception_t e;
|
707
1240
|
|
708
|
-
|
709
|
-
|
710
|
-
|
1241
|
+
e.magic_errno = magic_errno;
|
1242
|
+
e.magic_error = magic_error;
|
1243
|
+
e.klass = klass;
|
711
1244
|
|
712
|
-
|
1245
|
+
return magic_exception(&e);
|
713
1246
|
}
|
714
1247
|
|
715
1248
|
static VALUE
|
716
1249
|
magic_library_error(VALUE klass, void *data)
|
717
1250
|
{
|
718
|
-
|
719
|
-
|
720
|
-
|
1251
|
+
magic_exception_t e;
|
1252
|
+
const char *message = NULL;
|
1253
|
+
const char *empty = "(null)";
|
1254
|
+
magic_t cookie = data;
|
721
1255
|
|
722
|
-
|
723
|
-
assert(cookie != NULL && "Must be a valid pointer to `magic_t' type");
|
1256
|
+
UNUSED(empty);
|
724
1257
|
|
725
|
-
|
726
|
-
|
727
|
-
e.klass = klass;
|
1258
|
+
assert(cookie != NULL && \
|
1259
|
+
"Must be a valid pointer to `magic_t' type");
|
728
1260
|
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
e.magic_error = message;
|
733
|
-
}
|
1261
|
+
e.magic_errno = -1;
|
1262
|
+
e.magic_error = error(E_UNKNOWN);
|
1263
|
+
e.klass = klass;
|
734
1264
|
|
735
|
-
|
736
|
-
|
1265
|
+
message = magic_error_wrapper(cookie);
|
1266
|
+
if (message) {
|
1267
|
+
e.magic_errno = magic_errno_wrapper(cookie);
|
1268
|
+
e.magic_error = message;
|
1269
|
+
}
|
737
1270
|
|
738
|
-
|
1271
|
+
assert(strncmp(e.magic_error, empty, strlen(empty)) != 0 && \
|
1272
|
+
"Empty or invalid error message");
|
1273
|
+
|
1274
|
+
return magic_exception(&e);
|
739
1275
|
}
|
740
1276
|
|
741
1277
|
VALUE
|
742
1278
|
magic_lock(VALUE object, VALUE(*function)(ANYARGS), void *data)
|
743
1279
|
{
|
744
|
-
|
745
|
-
|
746
|
-
|
1280
|
+
magic_object_t *mo;
|
1281
|
+
|
1282
|
+
MAGIC_OBJECT(mo);
|
1283
|
+
rb_funcall(mo->mutex, rb_intern("lock"), 0);
|
1284
|
+
|
1285
|
+
return rb_ensure(function, (VALUE)data, magic_unlock, object);
|
747
1286
|
}
|
748
1287
|
|
749
1288
|
VALUE
|
750
1289
|
magic_unlock(VALUE object)
|
751
1290
|
{
|
752
|
-
|
753
|
-
|
754
|
-
|
1291
|
+
magic_object_t *mo;
|
1292
|
+
|
1293
|
+
MAGIC_OBJECT(mo);
|
1294
|
+
rb_funcall(mo->mutex, rb_intern("unlock"), 0);
|
1295
|
+
|
1296
|
+
return Qnil;
|
755
1297
|
}
|
756
1298
|
|
757
1299
|
static VALUE
|
758
|
-
magic_return(
|
1300
|
+
magic_return(void *data)
|
759
1301
|
{
|
760
|
-
|
761
|
-
|
1302
|
+
magic_arguments_t *ma = data;
|
1303
|
+
const char *unknown = "???";
|
1304
|
+
VALUE separator = Qundef;
|
1305
|
+
VALUE array = Qundef;
|
1306
|
+
VALUE string = Qundef;
|
1307
|
+
|
1308
|
+
string = CSTR2RVAL(ma->result);
|
1309
|
+
RB_GC_GUARD(string);
|
1310
|
+
|
1311
|
+
/*
|
1312
|
+
* The value below is a field separator that can be used to split results
|
1313
|
+
* when the CONTINUE flag is set causing all valid matches found by the
|
1314
|
+
* Magic library to be returned.
|
1315
|
+
*/
|
1316
|
+
if (ma->flags & MAGIC_CONTINUE)
|
1317
|
+
separator = CSTR2RVAL(MAGIC_CONTINUE_SEPARATOR);
|
1318
|
+
|
1319
|
+
if (ma->flags & MAGIC_EXTENSION) {
|
1320
|
+
/*
|
1321
|
+
* A possible I/O-related error has occurred, and there is very
|
1322
|
+
* little sense processing the results, so return string as-is.
|
1323
|
+
*/
|
1324
|
+
if (ma->status < 0)
|
1325
|
+
return string;
|
1326
|
+
/*
|
1327
|
+
* A number of Magic flags that support primarily files e.g.,
|
1328
|
+
* MAGIC_EXTENSION, etc., would not return a meaningful value for
|
1329
|
+
* directories and special files, and such. Thus, it's better to
|
1330
|
+
* return an empty string, to indicate lack of results, rather
|
1331
|
+
* than a confusing string consisting of three questions marks.
|
1332
|
+
*/
|
1333
|
+
if (strncmp(ma->result, unknown, strlen(unknown)) == 0)
|
1334
|
+
return CSTR2RVAL("");
|
1335
|
+
|
1336
|
+
separator = CSTR2RVAL(MAGIC_EXTENSION_SEPARATOR);
|
1337
|
+
}
|
1338
|
+
|
1339
|
+
if (ma->flags & (MAGIC_CONTINUE | MAGIC_EXTENSION)) {
|
1340
|
+
array = magic_split(string, separator);
|
1341
|
+
RB_GC_GUARD(array);
|
1342
|
+
return (RARRAY_LEN(array) > 1) ? array : magic_shift(array);
|
1343
|
+
}
|
1344
|
+
|
1345
|
+
return string;
|
1346
|
+
}
|
762
1347
|
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
1348
|
+
static inline int
|
1349
|
+
magic_get_flags(VALUE object)
|
1350
|
+
{
|
1351
|
+
return NUM2INT(rb_ivar_get(object, id_at_flags));
|
1352
|
+
}
|
767
1353
|
|
768
|
-
|
1354
|
+
static inline int
|
1355
|
+
magic_set_flags(VALUE object, VALUE value)
|
1356
|
+
{
|
1357
|
+
return NUM2INT(rb_ivar_set(object, id_at_flags, value));
|
769
1358
|
}
|
770
1359
|
|
1360
|
+
static inline VALUE
|
1361
|
+
magic_set_paths(VALUE object, VALUE value)
|
1362
|
+
{
|
1363
|
+
return rb_ivar_set(object, id_at_paths, value);
|
1364
|
+
}
|
1365
|
+
|
1366
|
+
static const rb_data_type_t rb_magic_type = {
|
1367
|
+
.wrap_struct_name = "magic",
|
1368
|
+
.function = {
|
1369
|
+
.dmark = magic_mark,
|
1370
|
+
.dfree = magic_free,
|
1371
|
+
.dsize = magic_size,
|
1372
|
+
#if defined(HAVE_RUBY_GC_COMPACT)
|
1373
|
+
.dcompact = magic_compact,
|
1374
|
+
#endif /* HAVE_RUBY_GC_COMPACT */
|
1375
|
+
},
|
1376
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
1377
|
+
};
|
1378
|
+
|
771
1379
|
void
|
772
1380
|
Init_magic(void)
|
773
1381
|
{
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
1382
|
+
id_at_paths = rb_intern("@paths");
|
1383
|
+
id_at_flags = rb_intern("@flags");
|
1384
|
+
|
1385
|
+
rb_cMagic = rb_define_class("Magic", rb_cObject);
|
1386
|
+
rb_define_alloc_func(rb_cMagic, magic_allocate);
|
1387
|
+
/*
|
1388
|
+
* Raised when _Magic_ encounters an error.
|
1389
|
+
*/
|
1390
|
+
rb_mgc_eError = rb_define_class_under(rb_cMagic, "Error", rb_eStandardError);
|
1391
|
+
/*
|
1392
|
+
* Stores current value of +errno+
|
1393
|
+
*/
|
1394
|
+
rb_define_attr(rb_mgc_eError, "errno", 1, 0);
|
1395
|
+
/*
|
1396
|
+
* Raised when
|
1397
|
+
*/
|
1398
|
+
rb_mgc_eMagicError = rb_define_class_under(rb_cMagic, "MagicError", rb_mgc_eError);
|
1399
|
+
/*
|
1400
|
+
* Raised when
|
1401
|
+
*/
|
1402
|
+
rb_mgc_eLibraryError = rb_define_class_under(rb_cMagic, "LibraryError", rb_mgc_eError);
|
1403
|
+
/*
|
1404
|
+
* Raised when
|
1405
|
+
*/
|
1406
|
+
rb_mgc_eParameterError = rb_define_class_under(rb_cMagic, "ParameterError", rb_mgc_eError);
|
1407
|
+
/*
|
1408
|
+
* Raised when
|
1409
|
+
*/
|
1410
|
+
rb_mgc_eFlagsError = rb_define_class_under(rb_cMagic, "FlagsError", rb_mgc_eError);
|
1411
|
+
/*
|
1412
|
+
* Raised when
|
1413
|
+
*/
|
1414
|
+
rb_mgc_eNotImplementedError = rb_define_class_under(rb_cMagic, "NotImplementedError", rb_mgc_eError);
|
1415
|
+
|
1416
|
+
rb_define_singleton_method(rb_cMagic, "do_not_auto_load", RUBY_METHOD_FUNC(rb_mgc_get_do_not_auto_load_global), 0);
|
1417
|
+
rb_define_singleton_method(rb_cMagic, "do_not_auto_load=", RUBY_METHOD_FUNC(rb_mgc_set_do_not_auto_load_global), 1);
|
1418
|
+
|
1419
|
+
rb_define_singleton_method(rb_cMagic, "do_not_stop_on_error", RUBY_METHOD_FUNC(rb_mgc_get_do_not_stop_on_error_global), 0);
|
1420
|
+
rb_define_singleton_method(rb_cMagic, "do_not_stop_on_error=", RUBY_METHOD_FUNC(rb_mgc_set_do_not_stop_on_error_global), 1);
|
1421
|
+
|
1422
|
+
rb_define_singleton_method(rb_cMagic, "version", RUBY_METHOD_FUNC(rb_mgc_version), 0);
|
1423
|
+
|
1424
|
+
rb_define_method(rb_cMagic, "initialize", RUBY_METHOD_FUNC(rb_mgc_initialize), -2);
|
1425
|
+
|
1426
|
+
rb_define_method(rb_cMagic, "do_not_stop_on_error", RUBY_METHOD_FUNC(rb_mgc_get_do_not_stop_on_error), 0);
|
1427
|
+
rb_define_method(rb_cMagic, "do_not_stop_on_error=", RUBY_METHOD_FUNC(rb_mgc_set_do_not_stop_on_error), 1);
|
1428
|
+
|
1429
|
+
rb_define_method(rb_cMagic, "open?", RUBY_METHOD_FUNC(rb_mgc_open_p), 0);
|
1430
|
+
rb_define_method(rb_cMagic, "close", RUBY_METHOD_FUNC(rb_mgc_close), 0);
|
1431
|
+
rb_define_method(rb_cMagic, "closed?", RUBY_METHOD_FUNC(rb_mgc_close_p), 0);
|
1432
|
+
|
1433
|
+
rb_define_method(rb_cMagic, "paths", RUBY_METHOD_FUNC(rb_mgc_get_paths), 0);
|
1434
|
+
|
1435
|
+
rb_define_method(rb_cMagic, "get_parameter", RUBY_METHOD_FUNC(rb_mgc_get_parameter), 1);
|
1436
|
+
rb_define_method(rb_cMagic, "set_parameter", RUBY_METHOD_FUNC(rb_mgc_set_parameter), 2);
|
1437
|
+
|
1438
|
+
rb_define_method(rb_cMagic, "flags", RUBY_METHOD_FUNC(rb_mgc_get_flags), 0);
|
1439
|
+
rb_define_method(rb_cMagic, "flags=", RUBY_METHOD_FUNC(rb_mgc_set_flags), 1);
|
1440
|
+
|
1441
|
+
rb_define_method(rb_cMagic, "file", RUBY_METHOD_FUNC(rb_mgc_file), 1);
|
1442
|
+
rb_define_method(rb_cMagic, "buffer", RUBY_METHOD_FUNC(rb_mgc_buffer), 1);
|
1443
|
+
rb_define_method(rb_cMagic, "descriptor", RUBY_METHOD_FUNC(rb_mgc_descriptor), 1);
|
1444
|
+
|
1445
|
+
rb_alias(rb_cMagic, rb_intern("fd"), rb_intern("descriptor"));
|
1446
|
+
|
1447
|
+
rb_define_method(rb_cMagic, "load", RUBY_METHOD_FUNC(rb_mgc_load), -2);
|
1448
|
+
rb_define_method(rb_cMagic, "load_buffers", RUBY_METHOD_FUNC(rb_mgc_load_buffers), -2);
|
1449
|
+
rb_define_method(rb_cMagic, "loaded?", RUBY_METHOD_FUNC(rb_mgc_load_p), 0);
|
1450
|
+
|
1451
|
+
rb_alias(rb_cMagic, rb_intern("load_files"), rb_intern("load"));
|
1452
|
+
|
1453
|
+
rb_define_method(rb_cMagic, "compile", RUBY_METHOD_FUNC(rb_mgc_compile), 1);
|
1454
|
+
rb_define_method(rb_cMagic, "check", RUBY_METHOD_FUNC(rb_mgc_check), 1);
|
1455
|
+
|
1456
|
+
rb_alias(rb_cMagic, rb_intern("valid?"), rb_intern("check"));
|
1457
|
+
|
1458
|
+
/*
|
1459
|
+
* Controls how many levels of recursion will be followed for
|
1460
|
+
* indirect magic entries.
|
1461
|
+
*/
|
1462
|
+
MAGIC_DEFINE_PARAMETER(INDIR_MAX);
|
1463
|
+
/*
|
1464
|
+
* Controls the maximum number of calls for name or use magic.
|
1465
|
+
*/
|
1466
|
+
MAGIC_DEFINE_PARAMETER(NAME_MAX);
|
1467
|
+
/*
|
1468
|
+
* Controls how many ELF program sections will be processed.
|
1469
|
+
*/
|
1470
|
+
MAGIC_DEFINE_PARAMETER(ELF_PHNUM_MAX);
|
1471
|
+
/*
|
1472
|
+
* Controls how many ELF sections will be processed.
|
1473
|
+
*/
|
1474
|
+
MAGIC_DEFINE_PARAMETER(ELF_SHNUM_MAX);
|
1475
|
+
/*
|
1476
|
+
* Controls how many ELF notes will be processed.
|
1477
|
+
*/
|
1478
|
+
MAGIC_DEFINE_PARAMETER(ELF_NOTES_MAX);
|
1479
|
+
/*
|
1480
|
+
* Controls the length limit for regular expression searches.
|
1481
|
+
*/
|
1482
|
+
MAGIC_DEFINE_PARAMETER(REGEX_MAX);
|
1483
|
+
/*
|
1484
|
+
* Controls the maximum number of bytes to read from a file.
|
1485
|
+
*/
|
1486
|
+
MAGIC_DEFINE_PARAMETER(BYTES_MAX);
|
1487
|
+
/*
|
1488
|
+
* No special handling and/or flags specified. Default behavior.
|
1489
|
+
*/
|
1490
|
+
MAGIC_DEFINE_FLAG(NONE);
|
1491
|
+
/*
|
1492
|
+
* Print debugging messages to standard error output.
|
1493
|
+
*/
|
1494
|
+
MAGIC_DEFINE_FLAG(DEBUG);
|
1495
|
+
/*
|
1496
|
+
* If the file queried is a symbolic link, follow it.
|
1497
|
+
*/
|
1498
|
+
MAGIC_DEFINE_FLAG(SYMLINK);
|
1499
|
+
/*
|
1500
|
+
* If the file is compressed, unpack it and look at the contents.
|
1501
|
+
*/
|
1502
|
+
MAGIC_DEFINE_FLAG(COMPRESS);
|
1503
|
+
/*
|
1504
|
+
* If the file is a block or character special device, then open
|
1505
|
+
* the device and try to look at the contents.
|
1506
|
+
*/
|
1507
|
+
MAGIC_DEFINE_FLAG(DEVICES);
|
1508
|
+
/*
|
1509
|
+
* Return a MIME type string, instead of a textual description.
|
1510
|
+
*/
|
1511
|
+
MAGIC_DEFINE_FLAG(MIME_TYPE);
|
1512
|
+
/*
|
1513
|
+
* Return all matches, not just the first.
|
1514
|
+
*/
|
1515
|
+
MAGIC_DEFINE_FLAG(CONTINUE);
|
1516
|
+
/*
|
1517
|
+
* Check the Magic database for consistency and print warnings to
|
1518
|
+
* standard error output.
|
1519
|
+
*/
|
1520
|
+
MAGIC_DEFINE_FLAG(CHECK);
|
1521
|
+
/*
|
1522
|
+
* Attempt to preserve access time (atime, utime or utimes) of the
|
1523
|
+
* file queried on systems that support such system calls.
|
1524
|
+
*/
|
1525
|
+
MAGIC_DEFINE_FLAG(PRESERVE_ATIME);
|
1526
|
+
/*
|
1527
|
+
* Do not convert unprintable characters to an octal representation.
|
1528
|
+
*/
|
1529
|
+
MAGIC_DEFINE_FLAG(RAW);
|
1530
|
+
/*
|
1531
|
+
* Treat operating system errors while trying to open files and follow
|
1532
|
+
* symbolic links as first class errors, instead of storing them in the
|
1533
|
+
* Magic library error buffer for retrieval later.
|
1534
|
+
*/
|
1535
|
+
MAGIC_DEFINE_FLAG(ERROR);
|
1536
|
+
/*
|
1537
|
+
* Return a MIME encoding, instead of a textual description.
|
1538
|
+
*/
|
1539
|
+
MAGIC_DEFINE_FLAG(MIME_ENCODING);
|
1540
|
+
/*
|
1541
|
+
* A shorthand for using MIME_TYPE and MIME_ENCODING flags together.
|
1542
|
+
*/
|
1543
|
+
MAGIC_DEFINE_FLAG(MIME);
|
1544
|
+
/*
|
1545
|
+
* Return the Apple creator and type.
|
1546
|
+
*/
|
1547
|
+
MAGIC_DEFINE_FLAG(APPLE);
|
1548
|
+
/*
|
1549
|
+
* Do not look for, or inside compressed files.
|
1550
|
+
*/
|
1551
|
+
MAGIC_DEFINE_FLAG(NO_CHECK_COMPRESS);
|
1552
|
+
/*
|
1553
|
+
* Do not look for, or inside tar archive files.
|
1554
|
+
*/
|
1555
|
+
MAGIC_DEFINE_FLAG(NO_CHECK_TAR);
|
1556
|
+
/*
|
1557
|
+
* Do not consult Magic files.
|
1558
|
+
*/
|
1559
|
+
MAGIC_DEFINE_FLAG(NO_CHECK_SOFT);
|
1560
|
+
/*
|
1561
|
+
* Check for EMX application type (only supported on EMX).
|
1562
|
+
*/
|
1563
|
+
MAGIC_DEFINE_FLAG(NO_CHECK_APPTYPE);
|
1564
|
+
/*
|
1565
|
+
* Do not check for ELF files (do not examine ELF file details).
|
1566
|
+
*/
|
1567
|
+
MAGIC_DEFINE_FLAG(NO_CHECK_ELF);
|
1568
|
+
/*
|
1569
|
+
* Do not check for various types of text files.
|
1570
|
+
*/
|
1571
|
+
MAGIC_DEFINE_FLAG(NO_CHECK_TEXT);
|
1572
|
+
/*
|
1573
|
+
* Do not check for CDF files.
|
1574
|
+
*/
|
1575
|
+
MAGIC_DEFINE_FLAG(NO_CHECK_CDF);
|
1576
|
+
/*
|
1577
|
+
* Do not check for CSV files.
|
1578
|
+
*/
|
1579
|
+
MAGIC_DEFINE_FLAG(NO_CHECK_CSV);
|
1580
|
+
/*
|
1581
|
+
* Do not look for known tokens inside ASCII files.
|
1582
|
+
*/
|
1583
|
+
MAGIC_DEFINE_FLAG(NO_CHECK_TOKENS);
|
1584
|
+
/*
|
1585
|
+
* Return a MIME encoding, instead of a textual description.
|
1586
|
+
*/
|
1587
|
+
MAGIC_DEFINE_FLAG(NO_CHECK_ENCODING);
|
1588
|
+
/*
|
1589
|
+
* Do not check for JSON files.
|
1590
|
+
*/
|
1591
|
+
MAGIC_DEFINE_FLAG(NO_CHECK_JSON);
|
1592
|
+
/*
|
1593
|
+
* Do not use built-in tests; only consult the Magic file.
|
1594
|
+
*/
|
1595
|
+
MAGIC_DEFINE_FLAG(NO_CHECK_BUILTIN);
|
1596
|
+
/*
|
1597
|
+
* Do not check for various types of text files, same as NO_CHECK_TEXT.
|
1598
|
+
*/
|
1599
|
+
MAGIC_DEFINE_FLAG(NO_CHECK_ASCII);
|
1600
|
+
/*
|
1601
|
+
* Do not look for Fortran sequences inside ASCII files.
|
1602
|
+
*/
|
1603
|
+
MAGIC_DEFINE_FLAG(NO_CHECK_FORTRAN);
|
1604
|
+
/*
|
1605
|
+
* Do not look for troff sequences inside ASCII files.
|
1606
|
+
*/
|
1607
|
+
MAGIC_DEFINE_FLAG(NO_CHECK_TROFF);
|
1608
|
+
/*
|
1609
|
+
* Return a slash-separated list of extensions for this file type.
|
1610
|
+
*/
|
1611
|
+
MAGIC_DEFINE_FLAG(EXTENSION);
|
1612
|
+
/*
|
1613
|
+
* Do not report on compression, only report about the uncompressed data.
|
1614
|
+
*/
|
1615
|
+
MAGIC_DEFINE_FLAG(COMPRESS_TRANSP);
|
1616
|
+
}
|
1617
|
+
|
1618
|
+
#if defined(__cplusplus)
|
1619
|
+
}
|
1620
|
+
#endif
|