ruby-magic 0.0.1
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 +7 -0
- data/AUTHORS +1 -0
- data/CHANGES +5 -0
- data/CHANGES.rdoc +5 -0
- data/COPYRIGHT +1 -0
- data/LICENSE +202 -0
- data/README +1 -0
- data/README.rdoc +7 -0
- data/Rakefile +78 -0
- data/TODO +21 -0
- data/VERSION +1 -0
- data/bin/magic +33 -0
- data/ext/magic/common.h +90 -0
- data/ext/magic/extconf.rb +115 -0
- data/ext/magic/functions.c +274 -0
- data/ext/magic/functions.h +100 -0
- data/ext/magic/ruby-magic.c +973 -0
- data/ext/magic/ruby-magic.h +244 -0
- data/lib/magic/core/file.rb +124 -0
- data/lib/magic/core/string.rb +76 -0
- data/lib/magic/version.rb +76 -0
- data/lib/magic.rb +204 -0
- data/ruby-magic.gemspec +68 -0
- data/test/test_constants.rb +47 -0
- data/test/test_magic.rb +260 -0
- metadata +153 -0
@@ -0,0 +1,274 @@
|
|
1
|
+
/* :enddoc: */
|
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
|
+
*/
|
20
|
+
|
21
|
+
#include "functions.h"
|
22
|
+
|
23
|
+
int suppress_error_output(void *data);
|
24
|
+
int restore_error_output(void *data);
|
25
|
+
|
26
|
+
int override_current_locale(void *data);
|
27
|
+
int restore_current_locale(void *data);
|
28
|
+
|
29
|
+
int
|
30
|
+
suppress_error_output(void *data)
|
31
|
+
{
|
32
|
+
int local_errno;
|
33
|
+
mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
|
34
|
+
|
35
|
+
save_t *s = data;
|
36
|
+
assert(s != NULL && "Must be a valid pointer to `save_t' type");
|
37
|
+
|
38
|
+
s->data.file.old_fd = -1;
|
39
|
+
s->data.file.new_fd = -1;
|
40
|
+
s->status = -1;
|
41
|
+
|
42
|
+
fflush(stderr);
|
43
|
+
fgetpos(stderr, &s->data.file.position);
|
44
|
+
|
45
|
+
s->data.file.old_fd = dup(fileno(stderr));
|
46
|
+
if (s->data.file.old_fd < 0) {
|
47
|
+
local_errno = errno;
|
48
|
+
goto out;
|
49
|
+
}
|
50
|
+
|
51
|
+
s->data.file.new_fd = open("/dev/null", O_WRONLY | O_APPEND, mode);
|
52
|
+
if (s->data.file.new_fd < 0) {
|
53
|
+
local_errno = errno;
|
54
|
+
|
55
|
+
if (dup2(s->data.file.old_fd, fileno(stderr)) < 0) {
|
56
|
+
local_errno = errno;
|
57
|
+
goto out;
|
58
|
+
}
|
59
|
+
|
60
|
+
close(s->data.file.old_fd);
|
61
|
+
goto out;
|
62
|
+
}
|
63
|
+
|
64
|
+
if (dup2(s->data.file.new_fd, fileno(stderr)) < 0) {
|
65
|
+
local_errno = errno;
|
66
|
+
goto out;
|
67
|
+
}
|
68
|
+
|
69
|
+
close(s->data.file.new_fd);
|
70
|
+
return 0;
|
71
|
+
|
72
|
+
out:
|
73
|
+
s->status = local_errno;
|
74
|
+
errno = s->status;
|
75
|
+
|
76
|
+
return -1;
|
77
|
+
}
|
78
|
+
|
79
|
+
int
|
80
|
+
restore_error_output(void *data)
|
81
|
+
{
|
82
|
+
int local_errno;
|
83
|
+
|
84
|
+
save_t *s = data;
|
85
|
+
assert(s != NULL && "Must be a valid pointer to `save_t' type");
|
86
|
+
|
87
|
+
if (s->data.file.old_fd < 0 && s->status != 0) {
|
88
|
+
return -1;
|
89
|
+
}
|
90
|
+
|
91
|
+
fflush(stderr);
|
92
|
+
|
93
|
+
if (dup2(s->data.file.old_fd, fileno(stderr)) < 0) {
|
94
|
+
local_errno = errno;
|
95
|
+
goto out;
|
96
|
+
}
|
97
|
+
|
98
|
+
close(s->data.file.old_fd);
|
99
|
+
clearerr(stderr);
|
100
|
+
fsetpos(stderr, &s->data.file.position);
|
101
|
+
|
102
|
+
if (setvbuf(stderr, NULL, _IONBF, 0) != 0) {
|
103
|
+
local_errno = errno;
|
104
|
+
goto out;
|
105
|
+
}
|
106
|
+
|
107
|
+
return 0;
|
108
|
+
|
109
|
+
out:
|
110
|
+
s->status = local_errno;
|
111
|
+
errno = s->status;
|
112
|
+
|
113
|
+
return -1;
|
114
|
+
}
|
115
|
+
|
116
|
+
int
|
117
|
+
override_current_locale(void *data)
|
118
|
+
{
|
119
|
+
char *current_locale = NULL;
|
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
|
+
}
|
140
|
+
|
141
|
+
assert(s->data.locale != NULL && "Must be a valid pointer to `char' type");
|
142
|
+
s->status = 0;
|
143
|
+
|
144
|
+
out:
|
145
|
+
return s->status;
|
146
|
+
}
|
147
|
+
|
148
|
+
int
|
149
|
+
restore_current_locale(void *data)
|
150
|
+
{
|
151
|
+
save_t *s = data;
|
152
|
+
assert(s != NULL && "Must be a valid pointer to `save_t' type");
|
153
|
+
|
154
|
+
if (!s->data.locale && s->status != 0) {
|
155
|
+
return -1;
|
156
|
+
}
|
157
|
+
|
158
|
+
if (!setlocale(LC_ALL, s->data.locale)) {
|
159
|
+
goto out;
|
160
|
+
}
|
161
|
+
|
162
|
+
assert(s->data.locale != NULL && "Must be a valid pointer to `char' type");
|
163
|
+
free(s->data.locale);
|
164
|
+
|
165
|
+
return 0;
|
166
|
+
|
167
|
+
out:
|
168
|
+
s->data.locale = NULL;
|
169
|
+
s->status = -1;
|
170
|
+
|
171
|
+
return -1;
|
172
|
+
}
|
173
|
+
|
174
|
+
inline const char*
|
175
|
+
magic_getpath_wrapper(void)
|
176
|
+
{
|
177
|
+
return magic_getpath(NULL, 0);
|
178
|
+
}
|
179
|
+
|
180
|
+
inline int
|
181
|
+
magic_setflags_wrapper(struct magic_set *ms, int flags)
|
182
|
+
{
|
183
|
+
if (flags < MAGIC_NONE || flags > MAGIC_NO_CHECK_BUILTIN) {
|
184
|
+
errno = EINVAL;
|
185
|
+
return -EINVAL;
|
186
|
+
}
|
187
|
+
|
188
|
+
#if !defined(HAVE_UTIME) && !defined(HAVE_UTIMES)
|
189
|
+
if (flags & MAGIC_PRESERVE_ATIME) {
|
190
|
+
errno = ENOSYS;
|
191
|
+
return -ENOSYS;
|
192
|
+
}
|
193
|
+
#endif
|
194
|
+
|
195
|
+
return magic_setflags(ms, flags);
|
196
|
+
}
|
197
|
+
|
198
|
+
inline int
|
199
|
+
magic_load_wrapper(struct magic_set *ms, const char *magicfile, int flags)
|
200
|
+
{
|
201
|
+
int rv;
|
202
|
+
|
203
|
+
MAGIC_FUNCTION(magic_load, rv, flags, ms, magicfile);
|
204
|
+
|
205
|
+
return rv;
|
206
|
+
}
|
207
|
+
|
208
|
+
inline int
|
209
|
+
magic_compile_wrapper(struct magic_set *ms, const char *magicfile, int flags)
|
210
|
+
{
|
211
|
+
int rv;
|
212
|
+
|
213
|
+
MAGIC_FUNCTION(magic_compile, rv, flags, ms, magicfile);
|
214
|
+
|
215
|
+
return rv;
|
216
|
+
}
|
217
|
+
|
218
|
+
inline int
|
219
|
+
magic_check_wrapper(struct magic_set *ms, const char *magicfile, int flags)
|
220
|
+
{
|
221
|
+
int rv;
|
222
|
+
|
223
|
+
MAGIC_FUNCTION(magic_check, rv, flags, ms, magicfile);
|
224
|
+
|
225
|
+
return rv;
|
226
|
+
}
|
227
|
+
|
228
|
+
inline const char*
|
229
|
+
magic_file_wrapper(struct magic_set *ms, const char* filename, int flags)
|
230
|
+
{
|
231
|
+
const char *cstring;
|
232
|
+
|
233
|
+
MAGIC_FUNCTION(magic_file, cstring, flags, ms, filename);
|
234
|
+
|
235
|
+
return cstring;
|
236
|
+
}
|
237
|
+
|
238
|
+
inline const char*
|
239
|
+
magic_buffer_wrapper(struct magic_set *ms, const void *buffer, size_t size, int flags)
|
240
|
+
{
|
241
|
+
const char *cstring;
|
242
|
+
|
243
|
+
MAGIC_FUNCTION(magic_buffer, cstring, flags, ms, buffer, size);
|
244
|
+
|
245
|
+
return cstring;
|
246
|
+
}
|
247
|
+
|
248
|
+
inline const char*
|
249
|
+
magic_descriptor_wrapper(struct magic_set *ms, int fd, int flags)
|
250
|
+
{
|
251
|
+
const char *cstring;
|
252
|
+
|
253
|
+
MAGIC_FUNCTION(magic_descriptor, cstring, flags, ms, fd);
|
254
|
+
|
255
|
+
return cstring;
|
256
|
+
}
|
257
|
+
|
258
|
+
inline int
|
259
|
+
magic_version_wrapper(void)
|
260
|
+
{
|
261
|
+
#if defined(HAVE_MAGIC_VERSION)
|
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
|
272
|
+
}
|
273
|
+
|
274
|
+
/* vim: set ts=8 sw=4 sts=2 et : */
|
@@ -0,0 +1,100 @@
|
|
1
|
+
/* :enddoc: */
|
2
|
+
|
3
|
+
/*
|
4
|
+
* functions.h
|
5
|
+
*
|
6
|
+
* Copyright 2013-2014 Krzysztof Wilczynski
|
7
|
+
*
|
8
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
9
|
+
* you may not use this file except in compliance with the License.
|
10
|
+
* You may obtain a copy of the License at
|
11
|
+
*
|
12
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
*
|
14
|
+
* Unless required by applicable law or agreed to in writing, software
|
15
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
+
* See the License for the specific language governing permissions and
|
18
|
+
* limitations under the License.
|
19
|
+
*/
|
20
|
+
|
21
|
+
#if !defined(_FUNCTIONS_H)
|
22
|
+
#define _FUNCTIONS_H 1
|
23
|
+
|
24
|
+
#if defined(__cplusplus)
|
25
|
+
extern "C" {
|
26
|
+
#endif
|
27
|
+
|
28
|
+
#include "common.h"
|
29
|
+
|
30
|
+
#if defined(HAVE_BROKEN_MAGIC)
|
31
|
+
# define OVERRIDE_LOCALE(f, r, ...) \
|
32
|
+
do { \
|
33
|
+
save_t __l_##f; \
|
34
|
+
override_current_locale(&(__l_##f)); \
|
35
|
+
r = f(__VA_ARGS__); \
|
36
|
+
restore_current_locale(&(__l_##f)); \
|
37
|
+
} while(0)
|
38
|
+
#else
|
39
|
+
# define OVERRIDE_LOCALE(f, r, ...) \
|
40
|
+
do { \
|
41
|
+
r = f(__VA_ARGS__); \
|
42
|
+
} while(0)
|
43
|
+
#endif
|
44
|
+
|
45
|
+
#define SUPPRESS_EVERYTHING(f, r, ...) \
|
46
|
+
do { \
|
47
|
+
save_t __e_##f; \
|
48
|
+
suppress_error_output(&(__e_##f)); \
|
49
|
+
OVERRIDE_LOCALE(f, r, __VA_ARGS__); \
|
50
|
+
restore_error_output(&(__e_##f)); \
|
51
|
+
} while(0)
|
52
|
+
|
53
|
+
#define MAGIC_FUNCTION(f, r, x, ...) \
|
54
|
+
do { \
|
55
|
+
if ((x) & MAGIC_ERROR) { \
|
56
|
+
OVERRIDE_LOCALE(f, r, __VA_ARGS__); \
|
57
|
+
} \
|
58
|
+
else { \
|
59
|
+
SUPPRESS_EVERYTHING(f, r, __VA_ARGS__); \
|
60
|
+
} \
|
61
|
+
} while(0)
|
62
|
+
|
63
|
+
struct file_data {
|
64
|
+
int old_fd;
|
65
|
+
int new_fd;
|
66
|
+
fpos_t position;
|
67
|
+
};
|
68
|
+
|
69
|
+
typedef struct file_data file_data_t;
|
70
|
+
|
71
|
+
struct save {
|
72
|
+
int status;
|
73
|
+
union {
|
74
|
+
file_data_t file;
|
75
|
+
char *locale;
|
76
|
+
} data;
|
77
|
+
};
|
78
|
+
|
79
|
+
typedef struct save save_t;
|
80
|
+
|
81
|
+
extern const char* magic_getpath_wrapper(void);
|
82
|
+
|
83
|
+
extern int magic_setflags_wrapper(struct magic_set *ms, int flags);
|
84
|
+
extern int magic_load_wrapper(struct magic_set *ms, const char *magicfile, int flags);
|
85
|
+
extern int magic_compile_wrapper(struct magic_set *ms, const char *magicfile, int flags);
|
86
|
+
extern int magic_check_wrapper(struct magic_set *ms, const char *magicfile, int flags);
|
87
|
+
|
88
|
+
extern const char* magic_file_wrapper(struct magic_set *ms, const char *filename, int flags);
|
89
|
+
extern const char* magic_buffer_wrapper(struct magic_set *ms, const void *buffer, size_t size, int flags);
|
90
|
+
extern const char* magic_descriptor_wrapper(struct magic_set *ms, int fd, int flags);
|
91
|
+
|
92
|
+
extern int magic_version_wrapper(void);
|
93
|
+
|
94
|
+
#if defined(__cplusplus)
|
95
|
+
}
|
96
|
+
#endif
|
97
|
+
|
98
|
+
#endif /* _FUNCTIONS_H */
|
99
|
+
|
100
|
+
/* vim: set ts=8 sw=4 sts=2 et : */
|