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