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