R_MAGIC(3)
π NAME π
okay bestie, welcome to R_MAGIC(3) from the Library Functions Manual β this is the page for r_magic, the file type detection library using magic numbers. Sheβs giving file(1) energy but as a library, and honestly? iconic.
π«Ά SYNOPSIS π«Ά
#include <r_magic.h>
β¨ DESCRIPTION β¨
The r_magic library provides file type detection using magic number patterns. It can identify file types by examining the content of files or buffers, similar to the Unix file(1) command.
The library uses a database of magic patterns that describe how to recognize different file formats based on their binary signatures, text patterns, and structural characteristics. No cap, itβs a whole vibe.
π INITIALIZATION π
A magic context holds the parsed magic database and runtime state; allocate one before attempting to probe files or buffers and free it when finished.
/* allocate and free a magic context */
RMagic *r_magic_new(int flags);
void r_magic_free(RMagic *ms);
/* example */
RMagic *magic = r_magic_new(R_MAGIC_NONE);
if (!magic) { /* handle allocation error */ }
After creating the instance you must load a magic database (or a buffer containing a magic database) before asking it to identify content.
/* load a database from a path or from memory */
bool r_magic_load(RMagic *ms, const char *magicfile);
bool r_magic_load_buffer(RMagic *ms, const ut8 *buf, size_t len);
π¦ FILE TYPE DETECTION π¦
Once a magic instance is loaded it can inspect in-memory buffers. The function returns a pointer to an internal, NUL-terminated string describing the matching type (do not free it). If no match is found it returns NULL and you may call r_magic_error() to obtain diagnostics.
/* signatures */
const char *r_magic_buffer(RMagic *ms, const void *buf, size_t nb);
Use the buffer API when the data is already in memory (for example a block read from a file or a memory map). libr/core uses this approach when detecting the type of the current block being inspected (see libr/core/cmd_magic.inc.c), then combines the returned description with further actions (flags, printing or nested probes using offsets).
/* example: probe a memory buffer */
const char *type = r_magic_buffer(magic, data, data_len);
if (type) {
printf("Buffer type: %s0, type);
} else {
const char *err = r_magic_error(magic);
fprintf(stderr, "magic failed: %s0, err ? err : "unknown");
}
bestie, that returned string is internal β do not free it. π
πΈ CONFIGURATION FLAGS πΈ
Flags control how the magic engine behaves (what it searches for and the format of the output). Set flags when creating the instance or at runtime with r_magic_setflags():
void r_magic_setflags(RMagic *ms, int flags);
Common flags include MIME-only output or enabling debug diagnostics; many others tune which checks are performed (compressed files, ELF details, etc.).
R_MAGIC_NONEβ No special flagsR_MAGIC_DEBUGβ Enable debugging outputR_MAGIC_MIME_TYPEβ Return only MIME typeR_MAGIC_MIME_ENCODINGβ Return only MIME encodingR_MAGIC_CONTINUEβ Return all matches, not just firstR_MAGIC_RAWβ Do not translate unprintable charactersR_MAGIC_CHECK_TEXTβ Check text magic entries after binary magic entries miss
Periodt. Thatβs the flag roster. π«Ά
π ERROR HANDLING π
The magic API reports human-readable error messages and an errno-like value when operations fail (for example, inability to open the magic file or parse its contents). Query these functions after an operation returns NULL/false.
const char *r_magic_error(RMagic *ms);
int r_magic_errno(RMagic *ms);
Callers should always check the return value of load/probe functions and then inspect r_magic_error for diagnostics. In long-running programs keep the magic instance around and reload only when the database changes (this is the pattern used in libr/core).
π DATABASE MANAGEMENT π
The magic database can be loaded from the system default path, from a specific file, or from a buffer in memory. r_magic_load_buffer accepts either text magic source or compiled .mgc bytes already resident in memory. Helper functions also allow compiling and syntax-checking magic files.
/* signatures */
bool r_magic_load(RMagic *ms, const char *magicfile);
bool r_magic_load_buffer(RMagic *ms, const ut8 *buf, size_t len);
bool r_magic_compile(RMagic *ms, const char *magicfile);
bool r_magic_check(RMagic *ms, const char *magicfile);
In practice libr/core will call r_magic_load once (using the dir.magic configuration key) and reuse the returned context for multiple buffer probes. If you wish to supply a custom database at runtime use r_magic_load_buffer and keep the database itself out of the filesystem path.
/* example: load custom magic then probe a buffer */
if (!r_magic_load_buffer(magic, magic_db, magic_db_len)) {
fprintf(stderr, "failed to load magic: %s0, r_magic_error(magic));
}
const char *t = r_magic_buffer(magic, data, data_len);
π SUPPORTED FORMATS π
The library can detect hundreds of file formats including:
- Executable formats (ELF, PE, Mach-O)
- Archives (ZIP, TAR, RAR)
- Images (JPEG, PNG, GIF, BMP)
- Documents (PDF, DOC, XLS)
- Audio/Video (MP3, MP4, AVI)
- Compressed files (GZ, BZ2, XZ)
- And many others
The following examples demonstrate common, practical usages of the API.
π Examples π
- Simple command-line file probe using an application-managed file read and
r_magic_buffer.
#include <r_magic.h>
#include <r_util/r_file.h>
#include <stdio.h>
int main(int argc, char **argv) {
size_t len = 0;
char *data;
if (argc < 2) { return 1; }
RMagic *m = r_magic_new(R_MAGIC_NONE);
if (!m) { perror("r_magic_new"); return 1; }
if (!r_magic_load(m, "/usr/share/radare2/magic.mgc")) {
fprintf(stderr, "load failed: %s0, r_magic_error(m));
r_magic_free(m);
return 1;
}
data = r_file_slurp(argv[1], &len);
if (!data) {
perror(argv[1]);
r_magic_free(m);
return 1;
}
const char *t = r_magic_buffer(m, data, len);
if (t) printf("%s: %s0, argv[1], t);
free(data);
r_magic_free(m);
return 0;
}
- Inspecting an in-memory block and reacting to generic "data" results.
libr/coreprobes the current block and, when the result is generic (for example "data"), it may choose to continue searching at a different alignment or attempt more specific heuristics.
RMagic *m = r_magic_new(0);
r_magic_load(m, "/usr/share/radare2/magic.mgc");
const char *info = r_magic_buffer(m, block, block_len);
if (info) {
if (!strcmp(info, "data")) {
/* fallback: try different alignments or other detectors */
} else {
printf("info: %s0, info);
}
}
r_magic_free(m);
- Request MIME-only output β useful when integrating magic into automated pipelines.
r_magic_setflags(m, R_MAGIC_MIME_TYPE);
const char *mime = r_magic_buffer(m, data, size);
printf("MIME: %s0, mime ? mime : "unknown");
π«Ά SEE ALSO π«Ά
xoxo, this page was brought to you by Debian Β· September 21, 2025 π β¨
π¦ where this page comes from
- arch rolling: radare2 6.2.2-1 Β· GPL-3.0-only AND LGPL-3.0-only
- nixpkgs unstable: radare2 6.2.4
- opensuse-leap 16.0: radare2 6.2.2-bp160.1.1 Β· GPL-3.0-only AND LGPL-3.0-only
- opensuse-leap 16.0: radare2 6.2.2-bp160.1.1 Β· GPL-3.0-only AND LGPL-3.0-only
- opensuse-leap 16.0: radare2 6.2.2-bp160.1.1 Β· GPL-3.0-only AND LGPL-3.0-only
- opensuse-leap 16.0: radare2 6.2.2-bp160.1.1 Β· GPL-3.0-only AND LGPL-3.0-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms