---
name: "r_magic"
section: "3"
platform: "linux"
package: "radare2"
version: "6.2.2-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/r_magic"
---

# r\_magic(3)

File type detection library using magic numbers

## NAME

**r\_magic** – File type detection library using magic numbers

## 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)](/file/1.md) 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.

## 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");
}
```

## 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 flags

- R\_MAGIC\_DEBUG

  Enable debugging output

- R\_MAGIC\_MIME\_TYPE

  Return only MIME type

- R\_MAGIC\_MIME\_ENCODING

  Return only MIME encoding

- R\_MAGIC\_CONTINUE

  Return all matches, not just first

- R\_MAGIC\_RAW

  Do not translate unprintable characters

- R\_MAGIC\_CHECK\_TEXT

  Check text magic entries after binary magic entries miss

## 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.

1\) 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;
}
```

2\) Inspecting an in-memory block and reacting to generic "data" results.\
    \`libr/core\` probes 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);
```

3\) 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

[r\_bin(3)](/r_bin/3.md), [r\_util(3)](/r_util/3.md)
