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