Обычный режим работы
This commit is contained in:
parent
aa214dcf96
commit
62be8600c6
4 changed files with 308 additions and 636 deletions
123
c/main.c
Normal file
123
c/main.c
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
// gcc -O2 -Wall -Wextra -o main main.c
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <sys/fanotify.h> // <-- прототипы fanotify_*
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/uio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h> // PATH_MAX
|
||||
|
||||
#ifndef AT_FDCWD
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
|
||||
/* Настройки из твоего D-кода */
|
||||
#define INIT_FLAGS (FAN_CLASS_PRE_CONTENT | FAN_CLOEXEC | FAN_NONBLOCK)
|
||||
#define EVENT_FLAGS (O_RDONLY | O_LARGEFILE | O_CLOEXEC)
|
||||
#define BASE_FLAGS (FAN_MARK_ADD)
|
||||
#define PERM_MASK (FAN_OPEN_PERM | FAN_ACCESS_PERM | FAN_OPEN_EXEC_PERM | FAN_OPEN | FAN_CLOSE_WRITE)
|
||||
#define BUF_SZ (64 * 1024)
|
||||
|
||||
/* Простой лог */
|
||||
static void log_line(const char *s) {
|
||||
struct iovec v[2];
|
||||
static const char nl = '\n';
|
||||
v[0].iov_base = (void*)s; v[0].iov_len = strlen(s);
|
||||
v[1].iov_base = (void*)&nl; v[1].iov_len = 1;
|
||||
writev(STDERR_FILENO, v, 2);
|
||||
}
|
||||
|
||||
static ssize_t fd_path(int fd, char *buf, size_t cap) {
|
||||
char linkpath[64];
|
||||
int m = snprintf(linkpath, sizeof(linkpath), "/proc/self/fd/%d", fd);
|
||||
if (m <= 0 || (size_t)m >= sizeof(linkpath)) return -1;
|
||||
ssize_t r = readlink(linkpath, buf, cap - 1);
|
||||
if (r >= 0) buf[r] = '\0';
|
||||
return r;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int fan = fanotify_init(INIT_FLAGS, EVENT_FLAGS);
|
||||
if (fan == -1) { perror("fanotify_init"); return 1; }
|
||||
|
||||
/* метим /tmp и /home как файловые системы */
|
||||
if (fanotify_mark(fan, BASE_FLAGS | FAN_MARK_FILESYSTEM, PERM_MASK, AT_FDCWD, "/tmp") == -1) {
|
||||
perror("fanotify_mark(/tmp)"); return 1;
|
||||
}
|
||||
if (fanotify_mark(fan, BASE_FLAGS | FAN_MARK_FILESYSTEM, PERM_MASK, AT_FDCWD, "/home") == -1) {
|
||||
perror("fanotify_mark(/home)"); return 1;
|
||||
}
|
||||
|
||||
int ep = epoll_create1(EPOLL_CLOEXEC);
|
||||
if (ep == -1) { perror("epoll_create1"); return 1; }
|
||||
|
||||
struct epoll_event ev = { .events = EPOLLIN | EPOLLONESHOT };
|
||||
ev.data.u64 = 1; /* тег */
|
||||
if (epoll_ctl(ep, EPOLL_CTL_ADD, fan, &ev) == -1) { perror("epoll_ctl ADD"); return 1; }
|
||||
|
||||
char *buf = malloc(BUF_SZ);
|
||||
if (!buf) { perror("malloc"); return 1; }
|
||||
|
||||
log_line("fanomon: started (watching /tmp and /home)");
|
||||
|
||||
for (;;) {
|
||||
struct epoll_event out;
|
||||
int n = epoll_wait(ep, &out, 1, -1);
|
||||
if (n == -1) { if (errno == EINTR) continue; perror("epoll_wait"); break; }
|
||||
|
||||
if ((out.events & EPOLLIN) && out.data.u64 == 1) {
|
||||
for (;;) {
|
||||
ssize_t len = read(fan, buf, BUF_SZ);
|
||||
if (len == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) break;
|
||||
if (len <= 0) break;
|
||||
|
||||
struct fanotify_event_metadata *meta;
|
||||
for (meta = (struct fanotify_event_metadata*)buf;
|
||||
FAN_EVENT_OK(meta, len);
|
||||
meta = FAN_EVENT_NEXT(meta, len)) {
|
||||
|
||||
if (meta->vers != FANOTIFY_METADATA_VERSION) { log_line("metadata version mismatch"); continue; }
|
||||
if (meta->mask & FAN_Q_OVERFLOW) { log_line("queue overflow"); continue; }
|
||||
|
||||
/* Быстро отвечаем на PERM-события */
|
||||
if (meta->mask & (FAN_OPEN_PERM | FAN_ACCESS_PERM | FAN_OPEN_EXEC_PERM)) {
|
||||
struct fanotify_response resp = { .fd = meta->fd, .response = FAN_ALLOW };
|
||||
if (write(fan, &resp, sizeof(resp)) == -1) perror("fanotify_response");
|
||||
}
|
||||
|
||||
/* Лёгкий лог пути (после ответа) */
|
||||
if (meta->fd >= 0) {
|
||||
char path[PATH_MAX];
|
||||
if (fd_path(meta->fd, path, sizeof(path)) >= 0) {
|
||||
char line[PATH_MAX + 16];
|
||||
const char *tag =
|
||||
(meta->mask & FAN_OPEN) ? "OPEN " :
|
||||
(meta->mask & FAN_CLOSE_WRITE) ? "CLOSEW" :
|
||||
(meta->mask & FAN_ACCESS_PERM) ? "APERM " :
|
||||
(meta->mask & FAN_OPEN_PERM) ? "OPERM " :
|
||||
(meta->mask & FAN_OPEN_EXEC_PERM) ? "XPERM " : "EVENT ";
|
||||
snprintf(line, sizeof(line), "%s %s", tag, path);
|
||||
log_line(line);
|
||||
}
|
||||
close(meta->fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Реарм ONE_SHOT */
|
||||
ev.events = EPOLLIN | EPOLLONESHOT;
|
||||
ev.data.u64 = 1;
|
||||
if (epoll_ctl(ep, EPOLL_CTL_MOD, fan, &ev) == -1) { perror("epoll_ctl MOD"); break; }
|
||||
}
|
||||
}
|
||||
|
||||
free(buf);
|
||||
close(ep);
|
||||
close(fan);
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue