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.c
CHANGED
@@ -1,274 +1,352 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
* functions.c
|
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
|
-
*/
|
1
|
+
#if defined(__cplusplus)
|
2
|
+
extern "C" {
|
3
|
+
#endif
|
20
4
|
|
21
5
|
#include "functions.h"
|
22
6
|
|
23
|
-
int
|
7
|
+
int check_fd(int fd);
|
8
|
+
static int safe_dup(int fd);
|
9
|
+
static int safe_close(int fd);
|
10
|
+
static int safe_cloexec(int fd);
|
11
|
+
int override_error_output(void *data);
|
24
12
|
int restore_error_output(void *data);
|
25
13
|
|
26
|
-
int
|
27
|
-
int
|
28
|
-
|
29
|
-
int
|
30
|
-
suppress_error_output(void *data)
|
14
|
+
inline int
|
15
|
+
check_fd(int fd)
|
31
16
|
{
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
17
|
+
errno = 0;
|
18
|
+
if (fd < 0 || (fcntl(fd, F_GETFD) < 0 && errno == EBADF)) {
|
19
|
+
errno = EBADF;
|
20
|
+
return -EBADF;
|
21
|
+
}
|
37
22
|
|
38
|
-
|
39
|
-
|
40
|
-
s->status = -1;
|
23
|
+
return 0;
|
24
|
+
}
|
41
25
|
|
42
|
-
|
43
|
-
|
26
|
+
static int
|
27
|
+
safe_dup(int fd)
|
28
|
+
{
|
29
|
+
int new_fd;
|
30
|
+
int local_errno;
|
31
|
+
int flags = F_DUPFD;
|
44
32
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
goto out;
|
49
|
-
}
|
33
|
+
#if defined(HAVE_F_DUPFD_CLOEXEC)
|
34
|
+
flags = F_DUPFD_CLOEXEC;
|
35
|
+
#endif
|
50
36
|
|
51
|
-
|
52
|
-
|
53
|
-
|
37
|
+
new_fd = fcntl(fd, flags, fileno(stderr) + 1);
|
38
|
+
if (new_fd < 0 && errno == EINVAL) {
|
39
|
+
new_fd = dup(fd);
|
40
|
+
if (new_fd < 0) {
|
41
|
+
local_errno = errno;
|
42
|
+
goto error;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
if (safe_cloexec(new_fd) < 0) {
|
46
|
+
local_errno = errno;
|
47
|
+
goto error;
|
48
|
+
}
|
49
|
+
|
50
|
+
return new_fd;
|
51
|
+
error:
|
52
|
+
errno = local_errno;
|
53
|
+
return -1;
|
54
|
+
}
|
54
55
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
56
|
+
static int
|
57
|
+
safe_close(int fd)
|
58
|
+
{
|
59
|
+
int rv;
|
60
|
+
#if defined(HAVE_POSIX_CLOSE_RESTART)
|
61
|
+
rv = posix_close(fd, 0);
|
62
|
+
#else
|
63
|
+
rv = close(fd);
|
64
|
+
if (rv < 0 && errno == EINTR)
|
65
|
+
errno = EINPROGRESS;
|
66
|
+
#endif
|
59
67
|
|
60
|
-
|
61
|
-
|
62
|
-
}
|
68
|
+
return rv;
|
69
|
+
}
|
63
70
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
71
|
+
static inline int
|
72
|
+
safe_cloexec(int fd)
|
73
|
+
{
|
74
|
+
int local_errno;
|
75
|
+
int flags = fcntl(fd, F_GETFD);
|
76
|
+
|
77
|
+
if (flags < 0) {
|
78
|
+
local_errno = errno;
|
79
|
+
goto error;
|
80
|
+
}
|
81
|
+
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) {
|
82
|
+
local_errno = errno;
|
83
|
+
goto error;
|
84
|
+
}
|
85
|
+
|
86
|
+
return 0;
|
87
|
+
error:
|
88
|
+
errno = local_errno;
|
89
|
+
return -1;
|
90
|
+
}
|
68
91
|
|
69
|
-
|
70
|
-
|
92
|
+
int
|
93
|
+
override_error_output(void *data)
|
94
|
+
{
|
95
|
+
int local_errno;
|
96
|
+
mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
|
97
|
+
save_t *s = data;
|
71
98
|
|
72
|
-
|
73
|
-
|
74
|
-
|
99
|
+
#if defined(HAVE_O_CLOEXEC)
|
100
|
+
mode |= O_CLOEXEC;
|
101
|
+
#endif
|
75
102
|
|
76
|
-
|
103
|
+
assert(s != NULL && \
|
104
|
+
"Must be a valid pointer to `save_t' type");
|
105
|
+
|
106
|
+
s->file.old_fd = -1;
|
107
|
+
s->file.new_fd = -1;
|
108
|
+
s->status = -1;
|
109
|
+
|
110
|
+
fflush(stderr);
|
111
|
+
fgetpos(stderr, &s->file.position);
|
112
|
+
|
113
|
+
s->file.old_fd = safe_dup(fileno(stderr));
|
114
|
+
if (s->file.old_fd < 0) {
|
115
|
+
local_errno = errno;
|
116
|
+
goto error;
|
117
|
+
}
|
118
|
+
|
119
|
+
s->file.new_fd = open("/dev/null", O_WRONLY | O_APPEND, mode);
|
120
|
+
if (s->file.new_fd < 0) {
|
121
|
+
local_errno = errno;
|
122
|
+
|
123
|
+
if (dup2(s->file.old_fd, fileno(stderr)) < 0) {
|
124
|
+
local_errno = errno;
|
125
|
+
goto error;
|
126
|
+
}
|
127
|
+
|
128
|
+
safe_close(s->file.old_fd);
|
129
|
+
goto error;
|
130
|
+
}
|
131
|
+
if (safe_cloexec(s->file.new_fd) < 0) {
|
132
|
+
local_errno = errno;
|
133
|
+
goto error;
|
134
|
+
}
|
135
|
+
if (dup2(s->file.new_fd, fileno(stderr)) < 0) {
|
136
|
+
local_errno = errno;
|
137
|
+
goto error;
|
138
|
+
}
|
139
|
+
|
140
|
+
safe_close(s->file.new_fd);
|
141
|
+
|
142
|
+
return 0;
|
143
|
+
error:
|
144
|
+
s->status = local_errno;
|
145
|
+
errno = s->status;
|
146
|
+
return -1;
|
77
147
|
}
|
78
148
|
|
79
149
|
int
|
80
150
|
restore_error_output(void *data)
|
81
151
|
{
|
82
|
-
|
83
|
-
|
84
|
-
save_t *s = data;
|
85
|
-
assert(s != NULL && "Must be a valid pointer to `save_t' type");
|
152
|
+
int local_errno;
|
153
|
+
save_t *s = data;
|
86
154
|
|
87
|
-
|
88
|
-
|
89
|
-
}
|
155
|
+
assert(s != NULL && \
|
156
|
+
"Must be a valid pointer to `save_t' type");
|
90
157
|
|
91
|
-
|
158
|
+
if (s->file.old_fd < 0 && s->status != 0)
|
159
|
+
return -1;
|
92
160
|
|
93
|
-
|
94
|
-
local_errno = errno;
|
95
|
-
goto out;
|
96
|
-
}
|
161
|
+
fflush(stderr);
|
97
162
|
|
98
|
-
|
99
|
-
|
100
|
-
|
163
|
+
if (dup2(s->file.old_fd, fileno(stderr)) < 0) {
|
164
|
+
local_errno = errno;
|
165
|
+
goto error;
|
166
|
+
}
|
101
167
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
}
|
168
|
+
safe_close(s->file.old_fd);
|
169
|
+
clearerr(stderr);
|
170
|
+
fsetpos(stderr, &s->file.position);
|
106
171
|
|
107
|
-
|
172
|
+
if (setvbuf(stderr, NULL, _IONBF, 0) != 0) {
|
173
|
+
local_errno = errno;
|
174
|
+
goto error;
|
175
|
+
}
|
108
176
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
177
|
+
return 0;
|
178
|
+
error:
|
179
|
+
s->status = local_errno;
|
180
|
+
errno = s->status;
|
181
|
+
return -1;
|
114
182
|
}
|
115
183
|
|
116
|
-
|
117
|
-
|
184
|
+
inline magic_t
|
185
|
+
magic_open_wrapper(int flags)
|
118
186
|
{
|
119
|
-
|
120
|
-
|
121
|
-
save_t *s = data;
|
122
|
-
assert(s != NULL && "Must be a valid pointer to `save_t' type");
|
123
|
-
|
124
|
-
s->status = -1;
|
125
|
-
s->data.locale = NULL;
|
126
|
-
|
127
|
-
current_locale = setlocale(LC_ALL, NULL);
|
128
|
-
if (!current_locale) {
|
129
|
-
goto out;
|
130
|
-
}
|
131
|
-
|
132
|
-
s->data.locale = strndup(current_locale, strlen(current_locale));
|
133
|
-
if (!s->data.locale) {
|
134
|
-
goto out;
|
135
|
-
}
|
136
|
-
|
137
|
-
if (!setlocale(LC_ALL, "C")) {
|
138
|
-
goto out;
|
139
|
-
}
|
187
|
+
return magic_open(flags);
|
188
|
+
}
|
140
189
|
|
141
|
-
|
142
|
-
|
190
|
+
inline void
|
191
|
+
magic_close_wrapper(magic_t magic)
|
192
|
+
{
|
193
|
+
magic_close(magic);
|
194
|
+
}
|
143
195
|
|
144
|
-
|
145
|
-
|
196
|
+
inline const char*
|
197
|
+
magic_error_wrapper(magic_t magic)
|
198
|
+
{
|
199
|
+
return magic_error(magic);
|
146
200
|
}
|
147
201
|
|
148
|
-
int
|
149
|
-
|
202
|
+
inline int
|
203
|
+
magic_errno_wrapper(magic_t magic)
|
150
204
|
{
|
151
|
-
|
152
|
-
|
205
|
+
return magic_errno(magic);
|
206
|
+
}
|
153
207
|
|
154
|
-
|
155
|
-
|
156
|
-
|
208
|
+
inline const char*
|
209
|
+
magic_getpath_wrapper(void)
|
210
|
+
{
|
211
|
+
/*
|
212
|
+
* The second argument translates to same value as the
|
213
|
+
* FILE_LOAD constant, which when used results in this
|
214
|
+
* function calling the get_default_magic() internally.
|
215
|
+
*
|
216
|
+
* N.B. magic_getpath() also honors the "MAGIC"
|
217
|
+
* environment variable."
|
218
|
+
*/
|
219
|
+
return magic_getpath(NULL, 0);
|
220
|
+
}
|
157
221
|
|
158
|
-
|
159
|
-
|
160
|
-
|
222
|
+
inline int
|
223
|
+
magic_getparam_wrapper(magic_t magic, int parameter, void *value)
|
224
|
+
{
|
225
|
+
return magic_getparam(magic, parameter, value);
|
226
|
+
}
|
161
227
|
|
162
|
-
|
163
|
-
|
228
|
+
inline int
|
229
|
+
magic_setparam_wrapper(magic_t magic, int parameter, const void *value)
|
230
|
+
{
|
231
|
+
if (*(const int *)value < 0 || *(const size_t *)value > UINT_MAX) {
|
232
|
+
errno = EOVERFLOW;
|
233
|
+
return -EOVERFLOW;
|
234
|
+
}
|
164
235
|
|
165
|
-
|
236
|
+
if (parameter == MAGIC_PARAM_BYTES_MAX)
|
237
|
+
return magic_setparam(magic, parameter, value);
|
166
238
|
|
167
|
-
|
168
|
-
|
169
|
-
|
239
|
+
if (*(const size_t *)value > USHRT_MAX) {
|
240
|
+
errno = EOVERFLOW;
|
241
|
+
return -EOVERFLOW;
|
242
|
+
}
|
170
243
|
|
171
|
-
|
244
|
+
return magic_setparam(magic, parameter, value);
|
172
245
|
}
|
173
246
|
|
174
|
-
inline
|
175
|
-
|
247
|
+
inline int
|
248
|
+
magic_getflags_wrapper(magic_t magic)
|
176
249
|
{
|
177
|
-
|
250
|
+
#if defined(HAVE_MAGIC_GETFLAGS)
|
251
|
+
return magic_getflags(magic);
|
252
|
+
#else
|
253
|
+
UNUSED(magic);
|
254
|
+
errno = ENOSYS;
|
255
|
+
return -ENOSYS;
|
256
|
+
#endif
|
178
257
|
}
|
179
258
|
|
180
259
|
inline int
|
181
|
-
magic_setflags_wrapper(
|
260
|
+
magic_setflags_wrapper(magic_t magic, int flags)
|
182
261
|
{
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
262
|
+
if (flags < 0 || flags > 0xfffffff) {
|
263
|
+
errno = EINVAL;
|
264
|
+
return -EINVAL;
|
265
|
+
}
|
187
266
|
|
188
267
|
#if !defined(HAVE_UTIME) && !defined(HAVE_UTIMES)
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
268
|
+
if (flags & MAGIC_PRESERVE_ATIME) {
|
269
|
+
errno = ENOSYS;
|
270
|
+
return -ENOSYS;
|
271
|
+
}
|
193
272
|
#endif
|
194
273
|
|
195
|
-
|
274
|
+
return magic_setflags(magic, flags);
|
196
275
|
}
|
197
276
|
|
198
277
|
inline int
|
199
|
-
magic_load_wrapper(
|
278
|
+
magic_load_wrapper(magic_t magic, const char *magic_file, int flags)
|
200
279
|
{
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
return rv;
|
280
|
+
int rv;
|
281
|
+
MAGIC_FUNCTION(magic_load, rv, flags, magic, magic_file);
|
282
|
+
return rv;
|
206
283
|
}
|
207
284
|
|
208
285
|
inline int
|
209
|
-
|
286
|
+
magic_load_buffers_wrapper(magic_t magic, void **buffers, size_t *sizes, size_t count, int flags)
|
210
287
|
{
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
return rv;
|
288
|
+
int rv;
|
289
|
+
MAGIC_FUNCTION(magic_load_buffers, rv, flags, magic, buffers, sizes, count);
|
290
|
+
return rv;
|
216
291
|
}
|
217
292
|
|
218
293
|
inline int
|
219
|
-
|
294
|
+
magic_compile_wrapper(magic_t magic, const char *magic_file, int flags)
|
220
295
|
{
|
221
|
-
|
222
|
-
|
223
|
-
|
296
|
+
int rv;
|
297
|
+
MAGIC_FUNCTION(magic_compile, rv, flags, magic, magic_file);
|
298
|
+
return rv;
|
299
|
+
}
|
224
300
|
|
225
|
-
|
301
|
+
inline int
|
302
|
+
magic_check_wrapper(magic_t magic, const char *magic_file, int flags)
|
303
|
+
{
|
304
|
+
int rv;
|
305
|
+
MAGIC_FUNCTION(magic_check, rv, flags, magic, magic_file);
|
306
|
+
return rv;
|
226
307
|
}
|
227
308
|
|
228
309
|
inline const char*
|
229
|
-
magic_file_wrapper(
|
310
|
+
magic_file_wrapper(magic_t magic, const char* filename, int flags)
|
230
311
|
{
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
return cstring;
|
312
|
+
const char *cstring;
|
313
|
+
MAGIC_FUNCTION(magic_file, cstring, flags, magic, filename);
|
314
|
+
return cstring;
|
236
315
|
}
|
237
316
|
|
238
317
|
inline const char*
|
239
|
-
magic_buffer_wrapper(
|
318
|
+
magic_buffer_wrapper(magic_t magic, const void *buffer, size_t size, int flags)
|
240
319
|
{
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
return cstring;
|
320
|
+
const char *cstring;
|
321
|
+
MAGIC_FUNCTION(magic_buffer, cstring, flags, magic, buffer, size);
|
322
|
+
return cstring;
|
246
323
|
}
|
247
324
|
|
248
325
|
inline const char*
|
249
|
-
magic_descriptor_wrapper(
|
326
|
+
magic_descriptor_wrapper(magic_t magic, int fd, int flags)
|
250
327
|
{
|
251
|
-
|
328
|
+
int local_errno;
|
329
|
+
const char *cstring;
|
330
|
+
|
331
|
+
if (check_fd(fd) < 0) {
|
332
|
+
local_errno = errno;
|
333
|
+
goto error;
|
334
|
+
}
|
252
335
|
|
253
|
-
|
336
|
+
MAGIC_FUNCTION(magic_descriptor, cstring, flags, magic, fd);
|
337
|
+
return cstring;
|
254
338
|
|
255
|
-
|
339
|
+
error:
|
340
|
+
errno = local_errno;
|
341
|
+
return NULL;
|
256
342
|
}
|
257
343
|
|
258
344
|
inline int
|
259
345
|
magic_version_wrapper(void)
|
260
346
|
{
|
261
|
-
|
262
|
-
return magic_version();
|
263
|
-
#else
|
264
|
-
# if defined(HAVE_WARNING)
|
265
|
-
# warning "function `int magic_version(void)' not implemented"
|
266
|
-
# else
|
267
|
-
# pragma message("function `int magic_version(void)' not implemented")
|
268
|
-
# endif
|
269
|
-
errno = ENOSYS;
|
270
|
-
return -ENOSYS;
|
271
|
-
#endif
|
347
|
+
return magic_version();
|
272
348
|
}
|
273
349
|
|
274
|
-
|
350
|
+
#if defined(__cplusplus)
|
351
|
+
}
|
352
|
+
#endif
|