392 lines
14 KiB
D
392 lines
14 KiB
D
// Low-level wrapper over the C API fanotify for D.
|
||
// All values are taken from uapi <linux/fanotify.h>
|
||
// Низкоуровневая обёртка над C API fanotify для D.
|
||
// Все значения взяты из uapi <linux/fanotify.h>
|
||
|
||
module fanotify;
|
||
|
||
import core.stdc.stdint; // uint64_t and similar // uint64_t и т.п.
|
||
|
||
// FLAGS FOR fanotify_init(flags, event_f_flags)
|
||
// ФЛАГИ ДЛЯ fanotify_init(flags, event_f_flags)
|
||
|
||
// File descriptor group behavior
|
||
// Поведение файлового дескриптора группы
|
||
// Close fd on exec()
|
||
enum FAN_CLOEXEC = 0x0000_0001; // Закрывать fd при exec()
|
||
// Non-blocking read()
|
||
enum FAN_NONBLOCK = 0x0000_0002; // Неблокирующие read()
|
||
|
||
// Group class (defines the type of issued events)
|
||
// Класс группы (определяет тип выдаваемых событий)
|
||
// Notifications only (not PERM)
|
||
enum FAN_CLASS_NOTIF = 0x0000_0000; // Только уведомления (не PERM)
|
||
// Permissions for access to CONTENT
|
||
enum FAN_CLASS_CONTENT = 0x0000_0004; // Разрешения на доступ к СОДЕРЖИМОМУ (CONTENT)
|
||
// Permissions BEFORE access to content (PRE_CONTENT)
|
||
enum FAN_CLASS_PRE_CONTENT = 0x0000_0008; // Разрешения ДО доступа к содержимому (PRE_CONTENT)
|
||
|
||
deprecated enum FAN_ALL_CLASS_BITS = (FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | FAN_CLASS_PRE_CONTENT);
|
||
|
||
// Queue/mark limits
|
||
// Лимиты очереди/меток
|
||
// Unlimited event queue
|
||
enum FAN_UNLIMITED_QUEUE = 0x0000_0010; // Неограниченная очередь событий
|
||
// Unlimited number of marks
|
||
enum FAN_UNLIMITED_MARKS = 0x0000_0020; // Неограниченное число меток
|
||
// Enable audit
|
||
enum FAN_ENABLE_AUDIT = 0x0000_0040; // Включить аудит
|
||
|
||
// Reporting format in event metadata
|
||
// Формат отчётности в метаданных события
|
||
// Add PIDFD (if supported by kernel)
|
||
enum FAN_REPORT_PIDFD = 0x0000_0080; // Добавлять PIDFD (если поддерживается ядром)
|
||
// Report TID instead of PID
|
||
enum FAN_REPORT_TID = 0x0000_0100; // Сообщать TID вместо PID
|
||
// Report file-id (handle) instead of fd
|
||
enum FAN_REPORT_FID = 0x0000_0200; // Сообщать file-id (handle) вместо fd
|
||
// Report dir file-id
|
||
enum FAN_REPORT_DIR_FID = 0x0000_0400; // Сообщать dir file-id
|
||
// Report name (previously FAN_REPORT_DFID_NAME)
|
||
enum FAN_REPORT_NAME = 0x0000_0800; // Сообщать имя (ранее FAN_REPORT_DFID_NAME)
|
||
// Report target file-id
|
||
enum FAN_REPORT_TARGET_FID = 0x0000_1000; // Сообщать target file-id
|
||
// event->fd can report errors
|
||
enum FAN_REPORT_FD_ERROR = 0x0000_2000; // event->fd может сообщать ошибки
|
||
// Report mount events
|
||
enum FAN_REPORT_MNT = 0x0000_4000; // Сообщать события монтирования
|
||
|
||
// Convenient summary macros
|
||
// Удобные сводные макросы
|
||
enum FAN_REPORT_DFID_NAME = (FAN_REPORT_DIR_FID | FAN_REPORT_NAME);
|
||
enum FAN_REPORT_DFID_NAME_TARGET = (FAN_REPORT_DFID_NAME | FAN_REPORT_FID | FAN_REPORT_TARGET_FID);
|
||
|
||
deprecated enum FAN_ALL_INIT_FLAGS =
|
||
(FAN_CLOEXEC | FAN_NONBLOCK | FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE |
|
||
FAN_UNLIMITED_MARKS);
|
||
|
||
// The event_f_flags parameter for fanotify_init() — these are open(2) flags:
|
||
// O_RDONLY / O_WRONLY / O_RDWR | O_LARGEFILE etc. (from <fcntl.h>).
|
||
// Параметр event_f_flags для fanotify_init() — это флаги open(2):
|
||
// O_RDONLY / O_WRONLY / O_RDWR | O_LARGEFILE и т.п. (из <fcntl.h>).
|
||
|
||
// FLAGS FOR fanotify_mark(fanfd, flags, mask, dirfd, path)
|
||
// ФЛАГИ ДЛЯ fanotify_mark(fanfd, flags, mask, dirfd, path)
|
||
|
||
// Add/update mark
|
||
enum FAN_MARK_ADD = 0x0000_0001; // Добавить/обновить метку
|
||
// Remove mark
|
||
enum FAN_MARK_REMOVE = 0x0000_0002; // Удалить метку
|
||
// Do not follow symlinks (on path)
|
||
enum FAN_MARK_DONT_FOLLOW = 0x0000_0004; // Не переходить по симлинкам (на path)
|
||
// Path must be a directory
|
||
enum FAN_MARK_ONLYDIR = 0x0000_0008; // Path должен быть каталогом
|
||
// Attach to mount point
|
||
enum FAN_MARK_MOUNT = 0x0000_0010; // Навесить на точку монтирования
|
||
// Set ignored events
|
||
enum FAN_MARK_IGNORED_MASK = 0x0000_0020; // Задать игнорируемые события
|
||
// Ignore survives modification
|
||
enum FAN_MARK_IGNORED_SURV_MODIFY = 0x0000_0040; // Игнор сохраняется при модификации
|
||
// Remove all marks from group
|
||
enum FAN_MARK_FLUSH = 0x0000_0080; // Снять все метки у группы
|
||
// Attach to entire filesystem
|
||
enum FAN_MARK_FILESYSTEM = 0x0000_0100; // Навесить на всю ФС
|
||
// Mark can be evicted
|
||
enum FAN_MARK_EVICTABLE = 0x0000_0200; // Метка может быть evicted
|
||
// Ignore (mutually exclusive with IGNORED_MASK, new)
|
||
enum FAN_MARK_IGNORE = 0x0000_0400; // Игнорировать (взаимоисключающе с IGNORED_MASK, новое)
|
||
|
||
// These are NOT bitwise flags. Both bits can be used together.
|
||
// Это НЕ битовые флаги. Оба бита могут использоваться вместе.
|
||
// On inode
|
||
enum FAN_MARK_INODE = 0x0000_0000; // На inode
|
||
// On mount namespace
|
||
enum FAN_MARK_MNTNS = 0x0000_0110; // На mount namespace
|
||
|
||
// Convenient macro
|
||
// Удобный макрос
|
||
enum FAN_MARK_IGNORE_SURV = (FAN_MARK_IGNORE | FAN_MARK_IGNORED_SURV_MODIFY);
|
||
|
||
deprecated enum FAN_ALL_MARK_FLAGS =
|
||
(FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_DONT_FOLLOW | FAN_MARK_ONLYDIR |
|
||
FAN_MARK_MOUNT | FAN_MARK_IGNORED_MASK | FAN_MARK_IGNORED_SURV_MODIFY |
|
||
FAN_MARK_FLUSH);
|
||
|
||
// EVENT MASK BITS (mask) FOR fanotify_mark()
|
||
// БИТЫ МАСКИ СОБЫТИЙ (mask) ДЛЯ fanotify_mark()
|
||
|
||
// "Regular" events
|
||
// «Обычные» события
|
||
// Read (read)
|
||
enum FAN_ACCESS = 0x0000_0001; // Чтение (read)
|
||
// Write/modify
|
||
enum FAN_MODIFY = 0x0000_0002; // Запись/изменение
|
||
// Metadata (chmod/chown/utime)
|
||
enum FAN_ATTRIB = 0x0000_0004; // Метаданные (chmod/chown/utime)
|
||
// Closed after write
|
||
enum FAN_CLOSE_WRITE = 0x0000_0008; // Закрыт после записи
|
||
// Closed without write
|
||
enum FAN_CLOSE_NOWRITE = 0x0000_0010; // Закрыт без записи
|
||
// Opened
|
||
enum FAN_OPEN = 0x0000_0020; // Открыт
|
||
// Moved "from"
|
||
enum FAN_MOVED_FROM = 0x0000_0040; // Перемещён «из»
|
||
// Moved "to"
|
||
enum FAN_MOVED_TO = 0x0000_0080; // Перемещён «в»
|
||
// Created
|
||
enum FAN_CREATE = 0x0000_0100; // Создан
|
||
// Deleted
|
||
enum FAN_DELETE = 0x0000_0200; // Удалён
|
||
// Observed object deleted itself
|
||
enum FAN_DELETE_SELF = 0x0000_0400; // Удалён сам наблюдаемый объект
|
||
// Observed object moved itself
|
||
enum FAN_MOVE_SELF = 0x0000_0800; // Перемещён сам наблюдаемый объект
|
||
// Opened for execution
|
||
enum FAN_OPEN_EXEC = 0x0000_1000; // Открыт для исполнения
|
||
// Queue overflow
|
||
enum FAN_Q_OVERFLOW = 0x0000_4000; // Переполнение очереди
|
||
// Filesystem errors
|
||
enum FAN_FS_ERROR = 0x0000_8000; // Ошибки ФС
|
||
|
||
// Pre-content access hook
|
||
enum FAN_PRE_ACCESS = 0x0010_0000; // pre-content access hook
|
||
// Mount attached
|
||
enum FAN_MNT_ATTACH = 0x0100_0000; // mount attached
|
||
// Mount detached
|
||
enum FAN_MNT_DETACH = 0x0200_0000; // mount detached
|
||
// File renamed
|
||
enum FAN_RENAME = 0x1000_0000; // file renamed
|
||
|
||
// "Permission" events (require CLASS_CONTENT/PRE_CONTENT)
|
||
// События «разрешения» (требуют CLASS_CONTENT/PRE_CONTENT)
|
||
// Request for open() (fixed name/value)
|
||
enum FAN_OPEN_PERM = 0x0001_0000; // Запрос на open() (исправлено имя/значение)
|
||
// Request for content access (fixed name/value)
|
||
enum FAN_ACCESS_PERM = 0x0002_0000; // Запрос на доступ к содержимому (исправлено имя/значение)
|
||
// Request for open(O_EXEC)
|
||
enum FAN_OPEN_EXEC_PERM = 0x0004_0000; // Запрос на open(O_EXEC)
|
||
|
||
// Mask scope modifiers
|
||
// Модификаторы области действия маски
|
||
// Events on child objects of directory
|
||
enum FAN_EVENT_ON_CHILD = 0x0800_0000; // События на дочерние объекты каталога
|
||
// Event relates to directory
|
||
enum FAN_ONDIR = 0x4000_0000; // Событие относится к каталогу
|
||
|
||
// Composite convenient masks
|
||
// Составные удобные маски
|
||
enum FAN_CLOSE = (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE);
|
||
enum FAN_MOVE = (FAN_MOVED_FROM | FAN_MOVED_TO);
|
||
|
||
deprecated enum FAN_ALL_EVENTS =
|
||
(FAN_ACCESS | FAN_MODIFY | FAN_CLOSE | FAN_OPEN);
|
||
|
||
deprecated enum FAN_ALL_PERM_EVENTS =
|
||
(FAN_OPEN_PERM | FAN_ACCESS_PERM);
|
||
|
||
deprecated enum FAN_ALL_OUTGOING_EVENTS =
|
||
(FAN_ALL_EVENTS | FAN_ALL_PERM_EVENTS | FAN_Q_OVERFLOW);
|
||
|
||
// EVENT METADATA
|
||
// МЕТАДАННЫЕ СОБЫТИЯ
|
||
|
||
struct fanotify_event_metadata
|
||
{
|
||
// Total record length
|
||
uint event_len; // Общая длина записи
|
||
// Version (FANOTIFY_METADATA_VERSION)
|
||
ubyte vers; // Версия (FANOTIFY_METADATA_VERSION)
|
||
// Reserved
|
||
ubyte reserved; // Зарезервировано
|
||
// Length of this structure
|
||
ushort metadata_len; // Длина этой структуры
|
||
// __aligned_u64: Event/modifier bits
|
||
uint64_t mask; // __aligned_u64: Биты события/модификаторов
|
||
// File descriptor (or FAN_NOFD)
|
||
int fd; // Файловый дескриптор (или FAN_NOFD)
|
||
// PID or TID (if FAN_REPORT_TID)
|
||
int pid; // PID или TID (если FAN_REPORT_TID)
|
||
}
|
||
|
||
enum FANOTIFY_METADATA_VERSION = 3;
|
||
enum FAN_NOFD = -1;
|
||
enum FAN_NOPIDFD = FAN_NOFD;
|
||
enum FAN_EPIDFD = -2;
|
||
|
||
// ADDITIONAL INFO (FID / PIDFD / ERROR / etc.) IN EVENT TAIL
|
||
// ДОП. ИНФОРМАЦИЯ (FID / PIDFD / ERROR / etc.) В ХВОСТЕ СОБЫТИЯ
|
||
|
||
struct fanotify_event_info_header
|
||
{
|
||
// Type of records below
|
||
ubyte info_type; // Тип записей ниже
|
||
// Alignment
|
||
ubyte pad; // Выравнивание
|
||
// Length of this record
|
||
ushort len; // Длина этой записи
|
||
}
|
||
|
||
// Info record types (follow metadata)
|
||
// Типы info-записей (идут после metadata)
|
||
// File handle only
|
||
enum FAN_EVENT_INFO_TYPE_FID = 1; // Только file handle
|
||
// Dir handle + object name
|
||
enum FAN_EVENT_INFO_TYPE_DFID_NAME = 2; // Dir handle + имя объекта
|
||
// Dir handle
|
||
enum FAN_EVENT_INFO_TYPE_DFID = 3; // Dir handle
|
||
// PIDFD (if FAN_REPORT_PIDFD)
|
||
enum FAN_EVENT_INFO_TYPE_PIDFD = 4; // PIDFD (если FAN_REPORT_PIDFD)
|
||
// Error info
|
||
enum FAN_EVENT_INFO_TYPE_ERROR = 5; // Error info
|
||
// Range info
|
||
enum FAN_EVENT_INFO_TYPE_RANGE = 6; // Range info
|
||
// Mount info
|
||
enum FAN_EVENT_INFO_TYPE_MNT = 7; // Mount info
|
||
|
||
// Special info types for FAN_RENAME
|
||
enum FAN_EVENT_INFO_TYPE_OLD_DFID_NAME = 10;
|
||
enum FAN_EVENT_INFO_TYPE_NEW_DFID_NAME = 12;
|
||
|
||
struct __kernel_fsid_t
|
||
{
|
||
int[2] val;
|
||
}
|
||
|
||
// Common header for FID records
|
||
// Общий заголовок для FID-записей
|
||
struct fanotify_event_info_fid
|
||
{
|
||
fanotify_event_info_header hdr;
|
||
// Filesystem
|
||
__kernel_fsid_t fsid; // Файловая система
|
||
// Followed by variable length: unsigned char handle[]; (opaque struct file_handle)
|
||
}
|
||
|
||
// Compatible with open_by_handle_at()
|
||
// Совместимо с open_by_handle_at()
|
||
struct file_handle
|
||
{
|
||
// Length of f_handle
|
||
uint handle_bytes; // Длина f_handle
|
||
// Handle type
|
||
int handle_type; // Тип handle
|
||
// Flexible tail (actual handle bytes follow the structure)
|
||
ubyte[0] f_handle; // Гибкий хвост (реальные байты handle идут сразу за структурой)
|
||
}
|
||
|
||
// Structure for PIDFD
|
||
// Структура для PIDFD
|
||
struct fanotify_event_info_pidfd
|
||
{
|
||
fanotify_event_info_header hdr;
|
||
// __s32
|
||
int pidfd; // __s32
|
||
}
|
||
|
||
// Structure for ERROR
|
||
// Структура для ERROR
|
||
struct fanotify_event_info_error
|
||
{
|
||
fanotify_event_info_header hdr;
|
||
// __s32
|
||
int error; // __s32
|
||
// __u32
|
||
uint error_count; // __u32
|
||
}
|
||
|
||
// Structure for RANGE
|
||
// Структура для RANGE
|
||
struct fanotify_event_info_range
|
||
{
|
||
fanotify_event_info_header hdr;
|
||
// __u32
|
||
uint pad; // __u32
|
||
// __u64
|
||
uint64_t offset; // __u64
|
||
// __u64
|
||
uint64_t count; // __u64
|
||
}
|
||
|
||
// Structure for MNT
|
||
// Структура для MNT
|
||
struct fanotify_event_info_mnt
|
||
{
|
||
fanotify_event_info_header hdr;
|
||
// __u64
|
||
uint64_t mnt_id; // __u64
|
||
}
|
||
|
||
// STRUCTURES FOR RESPONSE (for PERM events)
|
||
// СТРУКТУРЫ ДЛЯ RESPONSE (для PERM-событий)
|
||
|
||
struct fanotify_response
|
||
{
|
||
// __s32
|
||
int fd; // __s32
|
||
// __u32
|
||
uint response; // __u32
|
||
}
|
||
|
||
// Additional information in response
|
||
// Дополнительная информация в response
|
||
enum FAN_RESPONSE_INFO_NONE = 0;
|
||
enum FAN_RESPONSE_INFO_AUDIT_RULE = 1;
|
||
|
||
struct fanotify_response_info_header
|
||
{
|
||
ubyte type;
|
||
ubyte pad;
|
||
ushort len;
|
||
}
|
||
|
||
struct fanotify_response_info_audit_rule
|
||
{
|
||
fanotify_response_info_header hdr;
|
||
// __u32
|
||
uint rule_number; // __u32
|
||
// __u32
|
||
uint subj_trust; // __u32
|
||
// __u32
|
||
uint obj_trust; // __u32
|
||
}
|
||
|
||
// Legit responses
|
||
enum FAN_ALLOW = 0x01;
|
||
enum FAN_DENY = 0x02;
|
||
// Bitmask to create audit record
|
||
enum FAN_AUDIT = 0x10; // Bitmask to create audit record
|
||
// Bitmask to indicate additional information
|
||
enum FAN_INFO = 0x20; // Bitmask to indicate additional information
|
||
|
||
// For DENY with errno
|
||
// Для DENY с errno
|
||
enum FAN_ERRNO_BITS = 8;
|
||
enum FAN_ERRNO_SHIFT = (32 - FAN_ERRNO_BITS);
|
||
enum FAN_ERRNO_MASK = ((1 << FAN_ERRNO_BITS) - 1);
|
||
|
||
// C API FUNCTION PROTOTYPES
|
||
// ПРОТОТИПЫ ФУНКЦИЙ C API
|
||
|
||
extern (C) int fanotify_init(uint flags, uint event_f_flags);
|
||
|
||
extern (C) int fanotify_mark(
|
||
int fanotify_fd,
|
||
uint flags,
|
||
uint64_t mask,// AT_FDCWD or directory fd
|
||
int dirfd, // AT_FDCWD или fd каталога
|
||
// Path or null for INODE/FILESYSTEM/MOUNT
|
||
const(char)* pathname // Путь или null при INODE/FILESYSTEM/MOUNT
|
||
|
||
);
|
||
|
||
// For working with FID: open object by handle (requires CAP_DAC_READ_SEARCH)
|
||
// Для работы с FID: открыть объект по handle (требует CAP_DAC_READ_SEARCH)
|
||
extern (C) int open_by_handle_at(int mount_fd, const(file_handle)* handle, int flags);
|
||
|
||
// HELPER FUNCTIONS (macros for working with metadata buffer)
|
||
// HELPER FUNCTIONS (макросы для работы с буфером metadata)
|
||
|
||
enum FAN_EVENT_METADATA_LEN = fanotify_event_metadata.sizeof;
|
||
|
||
// FAN_EVENT_NEXT(meta, len): len -= meta.event_len; return cast(fanotify_event_metadata*) (cast(char*) meta + meta.event_len);
|
||
// FAN_EVENT_OK(meta, len): (len >= FAN_EVENT_METADATA_LEN) && (meta.event_len >= FAN_EVENT_METADATA_LEN) && (meta.event_len <= len)
|