1#![cfg_attr(docsrs, feature(doc_cfg))]
63#![cfg_attr(docsrs, feature(doc_cfg_hide))]
64#![cfg_attr(docsrs, doc(cfg_hide(docsrs)))]
65#![cfg_attr(not(test), no_std)]
68
69use core::ffi::c_void;
70use core::ffi::{c_char, c_int};
71use usize as size_t; #[allow(non_camel_case_types)]
76#[repr(C)]
78pub struct magic_set {
79 _data: [u8; 0],
80 _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
81}
82
83#[allow(non_camel_case_types)]
84pub type magic_t = *mut magic_set;
85
86pub const MAGIC_NONE: c_int = 0x000_0000;
87pub const MAGIC_DEBUG: c_int = 0x000_0001;
88pub const MAGIC_SYMLINK: c_int = 0x000_0002;
89pub const MAGIC_COMPRESS: c_int = 0x000_0004;
90pub const MAGIC_DEVICES: c_int = 0x000_0008;
91pub const MAGIC_MIME_TYPE: c_int = 0x000_0010;
92pub const MAGIC_CONTINUE: c_int = 0x000_0020;
93pub const MAGIC_CHECK: c_int = 0x000_0040;
94pub const MAGIC_PRESERVE_ATIME: c_int = 0x000_0080;
95pub const MAGIC_RAW: c_int = 0x000_0100;
96pub const MAGIC_ERROR: c_int = 0x000_0200;
97pub const MAGIC_MIME_ENCODING: c_int = 0x000_0400;
98pub const MAGIC_MIME: c_int = MAGIC_MIME_TYPE | MAGIC_MIME_ENCODING;
99pub const MAGIC_APPLE: c_int = 0x00_0800;
100pub const MAGIC_EXTENSION: c_int = 0x100_0000;
101pub const MAGIC_COMPRESS_TRANSP: c_int = 0x200_0000;
102#[cfg_attr(docsrs, doc(cfg(feature = "v5-44")))]
103#[cfg(feature = "v5-44")]
104pub const MAGIC_NO_COMPRESS_FORK: c_int = 0x400_0000;
105pub const MAGIC_NODESC: c_int = MAGIC_EXTENSION | MAGIC_MIME | MAGIC_APPLE;
106
107pub const MAGIC_NO_CHECK_COMPRESS: c_int = 0x000_1000;
108pub const MAGIC_NO_CHECK_TAR: c_int = 0x000_2000;
109pub const MAGIC_NO_CHECK_SOFT: c_int = 0x000_4000;
110pub const MAGIC_NO_CHECK_APPTYPE: c_int = 0x000_8000;
111pub const MAGIC_NO_CHECK_ELF: c_int = 0x001_0000;
112pub const MAGIC_NO_CHECK_TEXT: c_int = 0x002_0000;
113pub const MAGIC_NO_CHECK_CDF: c_int = 0x004_0000;
114pub const MAGIC_NO_CHECK_CSV: c_int = 0x008_0000;
115pub const MAGIC_NO_CHECK_TOKENS: c_int = 0x010_0000;
116pub const MAGIC_NO_CHECK_ENCODING: c_int = 0x020_0000;
117pub const MAGIC_NO_CHECK_JSON: c_int = 0x040_0000;
118#[cfg_attr(docsrs, doc(cfg(feature = "v5-45")))]
119#[cfg(feature = "v5-45")]
120pub const MAGIC_NO_CHECK_SIMH: c_int = 0x080_0000;
121
122#[cfg(not(feature = "v5-45"))]
123pub const MAGIC_NO_CHECK_BUILTIN: c_int = MAGIC_NO_CHECK_COMPRESS |
124MAGIC_NO_CHECK_TAR |
125MAGIC_NO_CHECK_APPTYPE |
127MAGIC_NO_CHECK_ELF |
128MAGIC_NO_CHECK_TEXT |
129MAGIC_NO_CHECK_CSV |
130MAGIC_NO_CHECK_CDF |
131MAGIC_NO_CHECK_TOKENS |
132MAGIC_NO_CHECK_ENCODING |
133MAGIC_NO_CHECK_JSON;
134
135#[cfg(feature = "v5-45")]
136pub const MAGIC_NO_CHECK_BUILTIN: c_int = MAGIC_NO_CHECK_COMPRESS |
137MAGIC_NO_CHECK_TAR |
138MAGIC_NO_CHECK_APPTYPE |
140MAGIC_NO_CHECK_ELF |
141MAGIC_NO_CHECK_TEXT |
142MAGIC_NO_CHECK_CSV |
143MAGIC_NO_CHECK_CDF |
144MAGIC_NO_CHECK_TOKENS |
145MAGIC_NO_CHECK_ENCODING |
146MAGIC_NO_CHECK_JSON |
147MAGIC_NO_CHECK_SIMH;
148
149#[deprecated]
150pub const MAGIC_NO_CHECK_ASCII: c_int = MAGIC_NO_CHECK_TEXT;
151
152#[deprecated]
153pub const MAGIC_NO_CHECK_FORTRAN: c_int = 0x00_0000;
154#[deprecated]
155pub const MAGIC_NO_CHECK_TROFF: c_int = 0x00_0000;
156
157pub const MAGIC_PARAM_INDIR_MAX: c_int = 0;
162pub const MAGIC_PARAM_NAME_MAX: c_int = 1;
163pub const MAGIC_PARAM_ELF_PHNUM_MAX: c_int = 2;
164pub const MAGIC_PARAM_ELF_SHNUM_MAX: c_int = 3;
165pub const MAGIC_PARAM_ELF_NOTES_MAX: c_int = 4;
166pub const MAGIC_PARAM_REGEX_MAX: c_int = 5;
167pub const MAGIC_PARAM_BYTES_MAX: c_int = 6;
168#[cfg_attr(docsrs, doc(cfg(feature = "v5-40")))]
169#[cfg(feature = "v5-40")]
170pub const MAGIC_PARAM_ENCODING_MAX: c_int = 7;
171#[cfg_attr(docsrs, doc(cfg(feature = "v5-45")))]
172#[cfg(feature = "v5-45")]
173pub const MAGIC_PARAM_ELF_SHSIZE_MAX: c_int = 8;
174
175pub const FILE_LOAD: c_int = 0;
177pub const FILE_CHECK: c_int = 1;
178pub const FILE_COMPILE: c_int = 2;
179pub const FILE_LIST: c_int = 3;
180
181extern "C" {
182 pub fn magic_open(flags: c_int) -> magic_t;
183 pub fn magic_close(cookie: magic_t);
184
185 pub fn magic_getpath(magicfile: *const c_char, action: c_int) -> *const c_char;
186 pub fn magic_file(cookie: magic_t, filename: *const c_char) -> *const c_char;
187 pub fn magic_descriptor(cookie: magic_t, fd: c_int) -> *const c_char;
188 pub fn magic_buffer(cookie: magic_t, buffer: *const c_void, length: size_t) -> *const c_char;
189
190 pub fn magic_error(cookie: magic_t) -> *const c_char;
191 pub fn magic_getflags(cookie: magic_t) -> c_int;
192 #[must_use]
193 pub fn magic_setflags(cookie: magic_t, flags: c_int) -> c_int;
194
195 pub fn magic_version() -> c_int;
196 #[must_use]
197 pub fn magic_load(cookie: magic_t, filename: *const c_char) -> c_int;
198 #[must_use]
199 pub fn magic_load_buffers(
200 cookie: magic_t,
201 buffers: *mut *mut c_void,
202 sizes: *mut size_t,
203 nbuffers: size_t,
204 ) -> c_int;
205
206 #[must_use]
207 pub fn magic_compile(cookie: magic_t, filename: *const c_char) -> c_int;
208 #[must_use]
209 pub fn magic_check(cookie: magic_t, filename: *const c_char) -> c_int;
210 #[must_use]
211 pub fn magic_list(cookie: magic_t, filename: *const c_char) -> c_int;
212 pub fn magic_errno(cookie: magic_t) -> c_int;
213
214 #[must_use]
215 pub fn magic_setparam(cookie: magic_t, param: c_int, value: *const c_void) -> c_int;
216 #[must_use]
217 pub fn magic_getparam(cookie: magic_t, param: c_int, value: *mut c_void) -> c_int;
218}
219
220#[cfg(test)]
221mod tests {
222 use super::*;
223
224 #[test]
228 fn test_magic_open() {
229 unsafe {
230 magic_open(MAGIC_NONE);
231 }
232 }
233
234 #[test]
235 fn test_magic_close() {
236 unsafe {
237 magic_close(std::ptr::null_mut());
238 }
239 }
240
241 #[test]
242 fn test_magic_getpath() {
243 unsafe {
244 magic_getpath(std::ptr::null(), FILE_CHECK);
245 }
246 }
247
248 #[test]
249 fn test_magic_file() {
250 unsafe {
251 magic_file(std::ptr::null_mut(), std::ptr::null());
252 }
253 }
254
255 #[test]
256 fn test_magic_descriptor() {
257 unsafe {
258 magic_descriptor(std::ptr::null_mut(), -1);
259 }
260 }
261
262 #[test]
263 fn test_magic_buffer() {
264 unsafe {
265 magic_buffer(std::ptr::null_mut(), std::ptr::null(), 0);
266 }
267 }
268
269 #[test]
270 fn test_magic_error() {
271 unsafe {
272 magic_error(std::ptr::null_mut());
273 }
274 }
275
276 #[test]
277 fn test_magic_getflags() {
278 unsafe {
279 magic_getflags(std::ptr::null_mut());
280 }
281 }
282
283 #[test]
284 fn test_magic_setflags() {
285 unsafe {
286 let _ = magic_setflags(std::ptr::null_mut(), MAGIC_NONE);
287 }
288
289 }
291
292 #[test]
293 fn test_magic_version() {
294 unsafe {
295 magic_version();
296 }
297 }
298
299 #[test]
300 fn test_magic_load() {
301 unsafe {
302 let _ = magic_load(std::ptr::null_mut(), std::ptr::null());
303 }
304 }
305
306 #[test]
307 fn test_magic_load_buffers() {
308 unsafe {
309 let _ = magic_load_buffers(
310 std::ptr::null_mut(),
311 std::ptr::null_mut(),
312 std::ptr::null_mut(),
313 0,
314 );
315 }
316 }
317
318 #[test]
319 fn test_magic_compile() {
320 unsafe {
321 let _ = magic_compile(std::ptr::null_mut(), std::ptr::null());
322 }
323 }
324
325 #[test]
326 fn test_magic_check() {
327 unsafe {
328 let _ = magic_check(std::ptr::null_mut(), std::ptr::null());
329 }
330 }
331
332 #[test]
333 fn test_magic_list() {
334 unsafe {
335 let _ = magic_list(std::ptr::null_mut(), std::ptr::null());
336 }
337 }
338
339 #[test]
340 fn test_magic_errno() {
341 unsafe {
342 magic_errno(std::ptr::null_mut());
343 }
344 }
345
346 #[test]
347 fn test_magic_setparam() {
348 unsafe {
349 let _ = magic_setparam(
350 std::ptr::null_mut(),
351 MAGIC_PARAM_INDIR_MAX,
352 std::ptr::null(),
353 );
354 }
355 }
356
357 #[test]
358 fn test_magic_getparam() {
359 unsafe {
360 let _ = magic_getparam(
361 std::ptr::null_mut(),
362 MAGIC_PARAM_INDIR_MAX,
363 std::ptr::null_mut(),
364 );
365 }
366
367 #[cfg(feature = "v5-40")]
368 {
369 let mgc = unsafe { magic_open(MAGIC_NONE) };
370 assert_ne!(mgc, std::ptr::null_mut());
371
372 let mut val: size_t = 0;
373
374 let rv = unsafe {
375 magic_getparam(
376 mgc,
377 MAGIC_PARAM_ENCODING_MAX,
378 &mut val as *mut size_t as *mut _,
379 )
380 };
381 assert_ne!(rv, -1);
382
383 unsafe {
384 magic_close(mgc);
385 }
386 }
387
388 #[cfg(feature = "v5-45")]
389 {
390 let mgc = unsafe { magic_open(MAGIC_NONE) };
391 assert_ne!(mgc, std::ptr::null_mut());
392
393 let mut val: size_t = 0;
394
395 let rv = unsafe {
396 magic_getparam(
397 mgc,
398 MAGIC_PARAM_ELF_SHSIZE_MAX,
399 &mut val as *mut size_t as *mut _,
400 )
401 };
402 assert_ne!(rv, -1);
403
404 unsafe {
405 magic_close(mgc);
406 }
407 }
408 }
409}