ruby-magic-static 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/AUTHORS +1 -0
- data/CHANGELOG.md +60 -0
- data/COPYRIGHT +1 -0
- data/LICENSE +202 -0
- data/NOTICE +466 -0
- data/README.md +46 -0
- data/VERSION +1 -0
- data/ext/magic/common.h +132 -0
- data/ext/magic/extconf.rb +196 -0
- data/ext/magic/functions.c +344 -0
- data/ext/magic/functions.h +67 -0
- data/ext/magic/ruby-magic.c +1595 -0
- data/ext/magic/ruby-magic.h +307 -0
- data/kwilczynski-public.pem +25 -0
- data/lib/magic.rb +203 -0
- data/lib/magic/core/file.rb +66 -0
- data/lib/magic/core/string.rb +33 -0
- data/lib/magic/version.rb +42 -0
- metadata +73 -0
data/README.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# File Magic in Ruby
|
2
|
+
|
3
|
+
This is a fork of https://github.com/kwilczynski/ruby-magic to compile a
|
4
|
+
vendored copy of libmagic.
|
5
|
+
|
6
|
+
[![Build Status](https://travis-ci.org/kwilczynski/ruby-magic.svg)](https://travis-ci.org/kwilczynski/ruby-magic)
|
7
|
+
[![Documentation Status](https://inch-ci.org/github/kwilczynski/ruby-magic.svg)](https://inch-ci.org/github/kwilczynski/ruby-magic)
|
8
|
+
[![Gem Version](https://badge.fury.io/rb/ruby-magic.svg)](http://badge.fury.io/rb/ruby-magic)
|
9
|
+
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
|
10
|
+
|
11
|
+
## Introduction
|
12
|
+
|
13
|
+
Provides simple interface to [libmagic][1] for Ruby Programming Language.
|
14
|
+
|
15
|
+
## Table of Contents
|
16
|
+
|
17
|
+
1. [Contributing](#contributing)
|
18
|
+
2. [Versioning](#versioning)
|
19
|
+
3. [Author](#author)
|
20
|
+
4. [Copyright](#copyright)
|
21
|
+
5. [License](#license)
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for best practices and instructions on
|
26
|
+
setting up your development environment.
|
27
|
+
|
28
|
+
## Versioning
|
29
|
+
|
30
|
+
This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
31
|
+
For the versions available, see the tags on this repository.
|
32
|
+
|
33
|
+
## Author
|
34
|
+
|
35
|
+
Krzysztof Wilczyński (<kw@linux.com>)
|
36
|
+
|
37
|
+
## Copyright
|
38
|
+
|
39
|
+
Copyright 2013-2021 Krzysztof Wilczyński
|
40
|
+
|
41
|
+
## License
|
42
|
+
|
43
|
+
This project is licensed under the terms of the Apache License, Version 2.0 license.
|
44
|
+
To view the full license see the included [LICENSE](LICENSE) file.
|
45
|
+
|
46
|
+
[1]: https://en.wikipedia.org/wiki/File_(command)
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.0
|
data/ext/magic/common.h
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
#if !defined(_COMMON_H)
|
2
|
+
#define _COMMON_H 1
|
3
|
+
|
4
|
+
#if !defined(_GNU_SOURCE)
|
5
|
+
# define _GNU_SOURCE 1
|
6
|
+
#endif
|
7
|
+
|
8
|
+
#if !defined(_BSD_SOURCE)
|
9
|
+
# define _BSD_SOURCE 1
|
10
|
+
#endif
|
11
|
+
|
12
|
+
#if !defined(_DEFAULT_SOURCE)
|
13
|
+
# define _DEFAULT_SOURCE 1
|
14
|
+
#endif
|
15
|
+
|
16
|
+
#if defined(__cplusplus)
|
17
|
+
extern "C" {
|
18
|
+
#endif
|
19
|
+
|
20
|
+
#include <stdio.h>
|
21
|
+
#include <stdlib.h>
|
22
|
+
#include <limits.h>
|
23
|
+
#include <string.h>
|
24
|
+
#include <unistd.h>
|
25
|
+
#include <fcntl.h>
|
26
|
+
#include <errno.h>
|
27
|
+
#include <assert.h>
|
28
|
+
#include <sys/stat.h>
|
29
|
+
#include <magic.h>
|
30
|
+
#include <ruby.h>
|
31
|
+
|
32
|
+
#if defined(HAVE_RUBY_IO_H)
|
33
|
+
# include <ruby/io.h>
|
34
|
+
#else
|
35
|
+
# include <rubyio.h>
|
36
|
+
#endif
|
37
|
+
|
38
|
+
#if !defined(BIT)
|
39
|
+
# define BIT(n) (1 << (n))
|
40
|
+
#endif
|
41
|
+
|
42
|
+
#if !defined(UNUSED)
|
43
|
+
# define UNUSED(x) (void)(x)
|
44
|
+
#endif
|
45
|
+
|
46
|
+
#if defined(F_DUPFD_CLOEXEC)
|
47
|
+
# define HAVE_F_DUPFD_CLOEXEC 1
|
48
|
+
#endif
|
49
|
+
|
50
|
+
#if defined(O_CLOEXEC)
|
51
|
+
# define HAVE_O_CLOEXEC 1
|
52
|
+
#endif
|
53
|
+
|
54
|
+
#if defined(POSIX_CLOSE_RESTART)
|
55
|
+
# define HAVE_POSIX_CLOSE_RESTART 1
|
56
|
+
#endif
|
57
|
+
|
58
|
+
#define MAGIC_EXTENSION_SEPARATOR "/"
|
59
|
+
#define MAGIC_CONTINUE_SEPARATOR "\n- "
|
60
|
+
|
61
|
+
#if !defined(MAGIC_NO_CHECK_CSV)
|
62
|
+
# define MAGIC_NO_CHECK_CSV 0
|
63
|
+
#endif
|
64
|
+
|
65
|
+
#if !defined(MAGIC_NO_CHECK_JSON)
|
66
|
+
# define MAGIC_NO_CHECK_JSON 0
|
67
|
+
#endif
|
68
|
+
|
69
|
+
#define DATA_P(x) (RB_TYPE_P((x), T_DATA))
|
70
|
+
#define BOOLEAN_P(x) (RB_TYPE_P((x), T_TRUE) || RB_TYPE_P((x), T_FALSE))
|
71
|
+
#define STRING_P(x) (RB_TYPE_P((x), T_STRING))
|
72
|
+
#define ARRAY_P(x) (RB_TYPE_P((x), T_ARRAY))
|
73
|
+
#define FILE_P(x) (RB_TYPE_P((x), T_FILE))
|
74
|
+
|
75
|
+
#define RVAL2CBOOL(x) (RTEST(x))
|
76
|
+
#define CBOOL2RVAL(x) ((x) ? Qtrue : Qfalse)
|
77
|
+
|
78
|
+
#define RVAL2CSTR(x) (NIL_P(x) ? NULL : StringValueCStr(x))
|
79
|
+
#define CSTR2RVAL(x) ((x) == NULL ? Qnil : rb_str_new2(x))
|
80
|
+
|
81
|
+
#define RARRAY_EMPTY rb_ary_new()
|
82
|
+
#define RARRAY_EMPTY_P(a) (RARRAY_LEN(a) == 0)
|
83
|
+
#define RARRAY_FIRST(a) (RARRAY_EMPTY_P(a) ? Qnil : rb_ary_entry((a), 0))
|
84
|
+
|
85
|
+
#define CLASS_NAME(o) (NIL_P((o)) ? "nil" : rb_obj_classname((o)))
|
86
|
+
|
87
|
+
#if !defined(T_INTEGER)
|
88
|
+
# define T_INTEGER rb_cInteger
|
89
|
+
#endif
|
90
|
+
|
91
|
+
#if !defined(HAVE_RB_IO_T)
|
92
|
+
# define rb_io_t OpenFile
|
93
|
+
#endif
|
94
|
+
|
95
|
+
#if !defined(GetReadFile)
|
96
|
+
# define FPTR_TO_FD(p) ((p)->fd)
|
97
|
+
#else
|
98
|
+
# define FPTR_TO_FD(p) (fileno(GetReadFile(p)))
|
99
|
+
#endif
|
100
|
+
|
101
|
+
#define NOGVL_FUNCTION (VALUE (*)(void *))
|
102
|
+
|
103
|
+
#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) && \
|
104
|
+
defined(HAVE_RUBY_THREAD_H) && HAVE_RUBY_THREAD_H
|
105
|
+
# include <ruby/thread.h>
|
106
|
+
# define NOGVL(f, d) \
|
107
|
+
rb_thread_call_without_gvl((f), (d), RUBY_UBF_IO, NULL)
|
108
|
+
#elif defined(HAVE_RB_THREAD_BLOCKING_REGION)
|
109
|
+
# define NOGVL(f, d) \
|
110
|
+
rb_thread_blocking_region(NOGVL_FUNCTION(f), (d), RUBY_UBF_IO, NULL)
|
111
|
+
#else
|
112
|
+
# include <rubysig.h>
|
113
|
+
static inline VALUE
|
114
|
+
fake_blocking_region(VALUE (*f)(ANYARGS), void *data)
|
115
|
+
{
|
116
|
+
VALUE rv;
|
117
|
+
|
118
|
+
TRAP_BEG;
|
119
|
+
rv = f(data);
|
120
|
+
TRAP_END;
|
121
|
+
|
122
|
+
return rv;
|
123
|
+
}
|
124
|
+
# define NOGVL(f, d) \
|
125
|
+
fake_blocking_region(NOGVL_FUNCTION(f), (d))
|
126
|
+
#endif
|
127
|
+
|
128
|
+
#if defined(__cplusplus)
|
129
|
+
}
|
130
|
+
#endif
|
131
|
+
|
132
|
+
#endif /* _COMMON_H */
|
@@ -0,0 +1,196 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mkmf'
|
4
|
+
require 'digest'
|
5
|
+
require 'open-uri'
|
6
|
+
|
7
|
+
LIBMAGIC_TAG = '5.39'.freeze
|
8
|
+
|
9
|
+
workdir = Dir.pwd
|
10
|
+
libdir = File.join(workdir, 'file-' + LIBMAGIC_TAG)
|
11
|
+
gemdir = File.expand_path(File.join(__dir__, '../..'))
|
12
|
+
gem_ext_dir = File.join(gemdir, 'lib', 'ext')
|
13
|
+
gem_include_dir = File.join(gem_ext_dir, 'include')
|
14
|
+
gem_lib_dir = File.join(gem_ext_dir, 'lib')
|
15
|
+
build_lib_dir = File.join(libdir, 'src', '.libs')
|
16
|
+
|
17
|
+
expected_sha256 = 'f05d286a76d9556243d0cb05814929c2ecf3a5ba07963f8f70bfaaa70517fad1'
|
18
|
+
filename = "#{workdir}/file.tar.gz"
|
19
|
+
|
20
|
+
unless File.exist?(filename)
|
21
|
+
File.open(filename, 'wb') do |target_file|
|
22
|
+
URI.open("ftp://ftp.astron.com/pub/file/file-#{LIBMAGIC_TAG}.tar.gz", 'rb') do |read_file|
|
23
|
+
target_file.write(read_file.read)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
checksum = Digest::SHA256.hexdigest(File.read(filename))
|
28
|
+
|
29
|
+
if checksum != expected_sha256
|
30
|
+
raise "SHA256 of #{filename} does not match: got #{checksum}, expected #{expected_sha256}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
system("tar -xzf #{filename}") || raise('ERROR')
|
35
|
+
system("cd #{libdir} && ./configure --prefix=#{gem_ext_dir} && make install") || raise('ERROR')
|
36
|
+
|
37
|
+
$LOCAL_LIBS << '-lmagic'
|
38
|
+
$LIBPATH << gem_lib_dir
|
39
|
+
$CFLAGS << " -I #{libdir}/src"
|
40
|
+
|
41
|
+
def darwin?
|
42
|
+
RbConfig::CONFIG['target_os'] =~ /darwin/
|
43
|
+
end
|
44
|
+
|
45
|
+
def windows?
|
46
|
+
RbConfig::CONFIG['target_os'] =~ /mswin|mingw32|windows/
|
47
|
+
end
|
48
|
+
|
49
|
+
if ENV['CC']
|
50
|
+
RbConfig::CONFIG['CC'] = RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC']
|
51
|
+
end
|
52
|
+
|
53
|
+
ENV['CC'] = RbConfig::CONFIG['CC']
|
54
|
+
|
55
|
+
$CFLAGS += ' -std=c99 -fPIC'
|
56
|
+
$CFLAGS += ' -Wall -Wextra -pedantic'
|
57
|
+
|
58
|
+
if RbConfig::CONFIG['CC'] =~ /gcc/
|
59
|
+
$CFLAGS += ' -O3' unless $CFLAGS =~ /-O\d/
|
60
|
+
$CFLAGS += ' -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline'
|
61
|
+
end
|
62
|
+
|
63
|
+
unless darwin?
|
64
|
+
$LDFLAGS += ' -Wl,--as-needed -Wl,--no-undefined'
|
65
|
+
end
|
66
|
+
|
67
|
+
if windows?
|
68
|
+
$LDFLAGS += ' -static-libgcc'
|
69
|
+
end
|
70
|
+
|
71
|
+
%w[
|
72
|
+
CFLAGS
|
73
|
+
CXXFLAGS
|
74
|
+
CPPFLAGS
|
75
|
+
].each do |variable|
|
76
|
+
$CFLAGS += format(' %s', ENV[variable]) if ENV[variable]
|
77
|
+
end
|
78
|
+
|
79
|
+
$LDFLAGS += format(' %s', ENV['LDFLAGS']) if ENV['LDFLAGS']
|
80
|
+
|
81
|
+
unless have_header('ruby.h')
|
82
|
+
abort "\n" + (<<-EOS).gsub(/^[ ]{,3}/, '') + "\n"
|
83
|
+
You appear to be missing Ruby development libraries and/or header
|
84
|
+
files. You can install missing compile-time dependencies in one of
|
85
|
+
the following ways:
|
86
|
+
|
87
|
+
- Debian / Ubuntu
|
88
|
+
|
89
|
+
apt-get install ruby-dev
|
90
|
+
|
91
|
+
- Red Hat / CentOS / Fedora
|
92
|
+
|
93
|
+
yum install ruby-devel or dnf install ruby-devel
|
94
|
+
|
95
|
+
- Mac OS X (Darwin)
|
96
|
+
|
97
|
+
brew install ruby (for Homebrew, see https://brew.sh)
|
98
|
+
port install ruby2.6 (for MacPorts, see https://www.macports.org)
|
99
|
+
|
100
|
+
- OpenBSD / NetBSD
|
101
|
+
|
102
|
+
pkg_add ruby (for pkgsrc, see https://www.pkgsrc.org)
|
103
|
+
|
104
|
+
- FreeBSD
|
105
|
+
|
106
|
+
pkg install ruby (for FreeBSD Ports, see https://www.freebsd.org/ports)
|
107
|
+
|
108
|
+
Alternatively, you can use either of the following Ruby version
|
109
|
+
managers in order to install Ruby locally (for your user only)
|
110
|
+
and/or system-wide:
|
111
|
+
|
112
|
+
- Ruby Version Manager (for RVM, see https://rvm.io)
|
113
|
+
- Ruby Environment (for rbenv, see https://github.com/sstephenson/rbenv)
|
114
|
+
- Change Ruby (for chruby, see https://github.com/postmodern/chruby)
|
115
|
+
|
116
|
+
More information about how to install Ruby on various platforms
|
117
|
+
available at the following web site:
|
118
|
+
|
119
|
+
https://www.ruby-lang.org/en/documentation/installation
|
120
|
+
EOS
|
121
|
+
end
|
122
|
+
|
123
|
+
have_library('ruby')
|
124
|
+
|
125
|
+
have_func('rb_thread_call_without_gvl')
|
126
|
+
have_func('rb_thread_blocking_region')
|
127
|
+
|
128
|
+
unless have_header('magic.h')
|
129
|
+
abort "\n" + (<<-EOS).gsub(/^[ ]{,3}/, '') + "\n"
|
130
|
+
You appear to be missing libmagic(3) library and/or necessary header
|
131
|
+
files. You can install missing compile-time dependencies in one of
|
132
|
+
the following ways:
|
133
|
+
|
134
|
+
- Debian / Ubuntu
|
135
|
+
|
136
|
+
apt-get install libmagic-dev
|
137
|
+
|
138
|
+
- Red Hat / CentOS / Fedora
|
139
|
+
|
140
|
+
yum install file-devel or dns install file-devel
|
141
|
+
|
142
|
+
- Mac OS X (Darwin)
|
143
|
+
|
144
|
+
brew install libmagic (for Homebrew, see https://brew.sh)
|
145
|
+
port install libmagic (for MacPorts, see https://www.macports.org)
|
146
|
+
|
147
|
+
- OpenBSD / NetBSD
|
148
|
+
|
149
|
+
pkg_add file (for pkgsrc, see https://www.pkgsrc.org)
|
150
|
+
|
151
|
+
- FreeBSD
|
152
|
+
|
153
|
+
pkg install file (for FreeBSD Ports, see https://www.freebsd.org/ports)
|
154
|
+
|
155
|
+
Alternatively, you can download recent release of the file(1) package
|
156
|
+
from the following web site and attempt to compile libmagic(3) manually:
|
157
|
+
|
158
|
+
https://www.darwinsys.com/file
|
159
|
+
EOS
|
160
|
+
end
|
161
|
+
|
162
|
+
have_library('magic')
|
163
|
+
|
164
|
+
unless have_func('magic_getpath')
|
165
|
+
abort "\n" + (<<-EOS).gsub(/^[ ]{,3}/, '') + "\n"
|
166
|
+
Your version of libmagic(3) appears to be too old.
|
167
|
+
|
168
|
+
Please, consider upgrading to at least version 5.29 or newer,
|
169
|
+
if possible. For more information about file(1) command and
|
170
|
+
libmagic(3) please visit the following web site:
|
171
|
+
|
172
|
+
https://www.darwinsys.com/file
|
173
|
+
EOS
|
174
|
+
end
|
175
|
+
|
176
|
+
have_func('magic_getflags')
|
177
|
+
|
178
|
+
%w[
|
179
|
+
utime.h
|
180
|
+
sys/types.h
|
181
|
+
sys/time.h
|
182
|
+
].each do |h|
|
183
|
+
have_header(h)
|
184
|
+
end
|
185
|
+
|
186
|
+
%w[
|
187
|
+
utime
|
188
|
+
utimes
|
189
|
+
].each do |f|
|
190
|
+
have_func(f)
|
191
|
+
end
|
192
|
+
|
193
|
+
dir_config('magic', [gem_include_dir], [gem_lib_dir])
|
194
|
+
|
195
|
+
create_header
|
196
|
+
create_makefile('magic/magic')
|
@@ -0,0 +1,344 @@
|
|
1
|
+
#if defined(__cplusplus)
|
2
|
+
extern "C" {
|
3
|
+
#endif
|
4
|
+
|
5
|
+
#include "functions.h"
|
6
|
+
|
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);
|
12
|
+
int restore_error_output(void *data);
|
13
|
+
|
14
|
+
inline int
|
15
|
+
check_fd(int fd)
|
16
|
+
{
|
17
|
+
errno = 0;
|
18
|
+
if (fd < 0 || (fcntl(fd, F_GETFD) < 0 && errno == EBADF)) {
|
19
|
+
errno = EBADF;
|
20
|
+
return -EBADF;
|
21
|
+
}
|
22
|
+
|
23
|
+
return 0;
|
24
|
+
}
|
25
|
+
|
26
|
+
static int
|
27
|
+
safe_dup(int fd)
|
28
|
+
{
|
29
|
+
int new_fd;
|
30
|
+
int local_errno;
|
31
|
+
int flags = F_DUPFD;
|
32
|
+
|
33
|
+
#if defined(HAVE_F_DUPFD_CLOEXEC)
|
34
|
+
flags = F_DUPFD_CLOEXEC;
|
35
|
+
#endif
|
36
|
+
|
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
|
+
}
|
55
|
+
|
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
|
67
|
+
|
68
|
+
return rv;
|
69
|
+
}
|
70
|
+
|
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
|
+
}
|
91
|
+
|
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;
|
98
|
+
|
99
|
+
#if defined(HAVE_O_CLOEXEC)
|
100
|
+
mode |= O_CLOEXEC;
|
101
|
+
#endif
|
102
|
+
|
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;
|
147
|
+
}
|
148
|
+
|
149
|
+
int
|
150
|
+
restore_error_output(void *data)
|
151
|
+
{
|
152
|
+
int local_errno;
|
153
|
+
save_t *s = data;
|
154
|
+
|
155
|
+
assert(s != NULL && \
|
156
|
+
"Must be a valid pointer to `save_t' type");
|
157
|
+
|
158
|
+
if (s->file.old_fd < 0 && s->status != 0)
|
159
|
+
return -1;
|
160
|
+
|
161
|
+
fflush(stderr);
|
162
|
+
|
163
|
+
if (dup2(s->file.old_fd, fileno(stderr)) < 0) {
|
164
|
+
local_errno = errno;
|
165
|
+
goto error;
|
166
|
+
}
|
167
|
+
|
168
|
+
safe_close(s->file.old_fd);
|
169
|
+
clearerr(stderr);
|
170
|
+
fsetpos(stderr, &s->file.position);
|
171
|
+
|
172
|
+
if (setvbuf(stderr, NULL, _IONBF, 0) != 0) {
|
173
|
+
local_errno = errno;
|
174
|
+
goto error;
|
175
|
+
}
|
176
|
+
|
177
|
+
return 0;
|
178
|
+
error:
|
179
|
+
s->status = local_errno;
|
180
|
+
errno = s->status;
|
181
|
+
return -1;
|
182
|
+
}
|
183
|
+
|
184
|
+
inline magic_t
|
185
|
+
magic_open_wrapper(int flags)
|
186
|
+
{
|
187
|
+
return magic_open(flags);
|
188
|
+
}
|
189
|
+
|
190
|
+
inline void
|
191
|
+
magic_close_wrapper(magic_t magic)
|
192
|
+
{
|
193
|
+
magic_close(magic);
|
194
|
+
}
|
195
|
+
|
196
|
+
inline const char*
|
197
|
+
magic_error_wrapper(magic_t magic)
|
198
|
+
{
|
199
|
+
return magic_error(magic);
|
200
|
+
}
|
201
|
+
|
202
|
+
inline int
|
203
|
+
magic_errno_wrapper(magic_t magic)
|
204
|
+
{
|
205
|
+
return magic_errno(magic);
|
206
|
+
}
|
207
|
+
|
208
|
+
inline const char*
|
209
|
+
magic_getpath_wrapper(void)
|
210
|
+
{
|
211
|
+
return magic_getpath(NULL, 0);
|
212
|
+
}
|
213
|
+
|
214
|
+
inline int
|
215
|
+
magic_getparam_wrapper(magic_t magic, int parameter, void *value)
|
216
|
+
{
|
217
|
+
return magic_getparam(magic, parameter, value);
|
218
|
+
}
|
219
|
+
|
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
|
+
}
|
227
|
+
|
228
|
+
if (parameter == MAGIC_PARAM_BYTES_MAX)
|
229
|
+
return magic_setparam(magic, parameter, value);
|
230
|
+
|
231
|
+
if (*(const size_t *)value > USHRT_MAX) {
|
232
|
+
errno = EOVERFLOW;
|
233
|
+
return -EOVERFLOW;
|
234
|
+
}
|
235
|
+
|
236
|
+
return magic_setparam(magic, parameter, value);
|
237
|
+
}
|
238
|
+
|
239
|
+
inline int
|
240
|
+
magic_getflags_wrapper(magic_t magic)
|
241
|
+
{
|
242
|
+
#if defined(HAVE_MAGIC_GETFLAGS)
|
243
|
+
return magic_getflags(magic);
|
244
|
+
#else
|
245
|
+
UNUSED(magic);
|
246
|
+
errno = ENOSYS;
|
247
|
+
return -ENOSYS;
|
248
|
+
#endif
|
249
|
+
}
|
250
|
+
|
251
|
+
inline int
|
252
|
+
magic_setflags_wrapper(magic_t magic, int flags)
|
253
|
+
{
|
254
|
+
if (flags < 0 || flags > 0xfffffff) {
|
255
|
+
errno = EINVAL;
|
256
|
+
return -EINVAL;
|
257
|
+
}
|
258
|
+
|
259
|
+
#if !defined(HAVE_UTIME) && !defined(HAVE_UTIMES)
|
260
|
+
if (flags & MAGIC_PRESERVE_ATIME) {
|
261
|
+
errno = ENOSYS;
|
262
|
+
return -ENOSYS;
|
263
|
+
}
|
264
|
+
#endif
|
265
|
+
|
266
|
+
return magic_setflags(magic, flags);
|
267
|
+
}
|
268
|
+
|
269
|
+
inline int
|
270
|
+
magic_load_wrapper(magic_t magic, const char *magic_file, int flags)
|
271
|
+
{
|
272
|
+
int rv;
|
273
|
+
MAGIC_FUNCTION(magic_load, rv, flags, magic, magic_file);
|
274
|
+
return rv;
|
275
|
+
}
|
276
|
+
|
277
|
+
inline int
|
278
|
+
magic_load_buffers_wrapper(magic_t magic, void **buffers, size_t *sizes, size_t count, int flags)
|
279
|
+
{
|
280
|
+
int rv;
|
281
|
+
MAGIC_FUNCTION(magic_load_buffers, rv, flags, magic, buffers, sizes, count);
|
282
|
+
return rv;
|
283
|
+
}
|
284
|
+
|
285
|
+
inline int
|
286
|
+
magic_compile_wrapper(magic_t magic, const char *magic_file, int flags)
|
287
|
+
{
|
288
|
+
int rv;
|
289
|
+
MAGIC_FUNCTION(magic_compile, rv, flags, magic, magic_file);
|
290
|
+
return rv;
|
291
|
+
}
|
292
|
+
|
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;
|
299
|
+
}
|
300
|
+
|
301
|
+
inline const char*
|
302
|
+
magic_file_wrapper(magic_t magic, const char* filename, int flags)
|
303
|
+
{
|
304
|
+
const char *cstring;
|
305
|
+
MAGIC_FUNCTION(magic_file, cstring, flags, magic, filename);
|
306
|
+
return cstring;
|
307
|
+
}
|
308
|
+
|
309
|
+
inline const char*
|
310
|
+
magic_buffer_wrapper(magic_t magic, const void *buffer, size_t size, int flags)
|
311
|
+
{
|
312
|
+
const char *cstring;
|
313
|
+
MAGIC_FUNCTION(magic_buffer, cstring, flags, magic, buffer, size);
|
314
|
+
return cstring;
|
315
|
+
}
|
316
|
+
|
317
|
+
inline const char*
|
318
|
+
magic_descriptor_wrapper(magic_t magic, int fd, int flags)
|
319
|
+
{
|
320
|
+
int local_errno;
|
321
|
+
const char *cstring;
|
322
|
+
|
323
|
+
if (check_fd(fd) < 0) {
|
324
|
+
local_errno = errno;
|
325
|
+
goto error;
|
326
|
+
}
|
327
|
+
|
328
|
+
MAGIC_FUNCTION(magic_descriptor, cstring, flags, magic, fd);
|
329
|
+
return cstring;
|
330
|
+
|
331
|
+
error:
|
332
|
+
errno = local_errno;
|
333
|
+
return NULL;
|
334
|
+
}
|
335
|
+
|
336
|
+
inline int
|
337
|
+
magic_version_wrapper(void)
|
338
|
+
{
|
339
|
+
return magic_version();
|
340
|
+
}
|
341
|
+
|
342
|
+
#if defined(__cplusplus)
|
343
|
+
}
|
344
|
+
#endif
|