Добавлен вывод через библиотеку sdiff
This commit is contained in:
parent
aa214dcf96
commit
7f54a56ef5
2 changed files with 66 additions and 5 deletions
9
dub.json
9
dub.json
|
@ -8,7 +8,14 @@
|
|||
"name": "dwatch",
|
||||
"targetPath": "bin",
|
||||
"targetType": "executable",
|
||||
"libs": [
|
||||
"xdiff"
|
||||
],
|
||||
"dependencies": {
|
||||
"fanotify": "~>0.1.0"
|
||||
"fanotify": "~>0.1.0",
|
||||
"sdiff": {
|
||||
"repository": "git+git+https://git.zhirov.kz/dlang/sdiff.git",
|
||||
"version": "8c388b112360a9f5bf89b9aa12b1977b8967b219"
|
||||
}
|
||||
}
|
||||
}
|
62
source/app.d
62
source/app.d
|
@ -10,7 +10,7 @@ import core.sys.posix.sys.stat : fstat, stat_t;
|
|||
import core.stdc.errno : errno, EINTR;
|
||||
import core.stdc.string : strerror;
|
||||
import std.stdio : writeln, writefln, stderr;
|
||||
import std.file : isDir, readText, exists;
|
||||
import std.file : isDir, readText, exists, read;
|
||||
import std.string : strip, splitLines, startsWith, toStringz, fromStringz, split;
|
||||
import std.conv : to;
|
||||
import std.exception : enforce;
|
||||
|
@ -147,6 +147,8 @@ struct Session
|
|||
uint uid; // LOGINUID из /proc/PID/loginuid
|
||||
string filePathOpen; // путь, снятый на PERM
|
||||
bool changed; // был CLOSE_WRITE
|
||||
const(ubyte)[] fileBytesSource;
|
||||
const(ubyte)[] fileBytesDiff;
|
||||
}
|
||||
|
||||
__gshared Session[DevIno] gMap; // (pid,dev,ino) -> Session
|
||||
|
@ -184,12 +186,28 @@ ulong dirMask()
|
|||
FAN_OPEN | FAN_CLOSE_WRITE;
|
||||
}
|
||||
|
||||
ubyte[] readAllFromFd(int fd)
|
||||
{
|
||||
import std.array : appender;
|
||||
|
||||
ubyte[16_384] buf; // 16 KiB буфер
|
||||
auto output = appender!(ubyte[]);
|
||||
for (;;)
|
||||
{
|
||||
auto n = read(fd, buf.ptr, buf.length);
|
||||
if (n <= 0)
|
||||
break;
|
||||
output.put(buf[0 .. n]);
|
||||
}
|
||||
return output.data;
|
||||
}
|
||||
|
||||
/// ---- обработчики ----
|
||||
void onOpenPerm(FanotifyEvent ev, Epoll ep)
|
||||
{
|
||||
const pid = ev.pid;
|
||||
auto procName = readProcComm(pid);
|
||||
auto ids = readProcIds(pid); // <-- ruid + loginuid
|
||||
auto ids = readProcIds(pid);
|
||||
|
||||
DevIno key;
|
||||
if (!getDevIno(ev.eventFd, key, pid))
|
||||
|
@ -200,13 +218,26 @@ void onOpenPerm(FanotifyEvent ev, Epoll ep)
|
|||
|
||||
auto path = readlinkFdPath(ev.eventFd);
|
||||
|
||||
const(ubyte)[] content;
|
||||
try
|
||||
{
|
||||
if (path.length)
|
||||
{
|
||||
content = readAllFromFd(ev.eventFd);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
content = [];
|
||||
}
|
||||
|
||||
if (auto ps = key in gMap)
|
||||
{
|
||||
// уже есть
|
||||
}
|
||||
else
|
||||
{
|
||||
gMap[key] = Session(procName, ids.ruid, ids.uid, path, false);
|
||||
gMap[key] = Session(procName, ids.ruid, ids.uid, path, false, content);
|
||||
}
|
||||
|
||||
if (!(pid in gPidfdByPid))
|
||||
|
@ -214,7 +245,7 @@ void onOpenPerm(FanotifyEvent ev, Epoll ep)
|
|||
int pfd = -1;
|
||||
try
|
||||
{
|
||||
pfd = pidfd_open(pid, 0); // на твоей системе так ок
|
||||
pfd = pidfd_open(pid, 0);
|
||||
if (pfd < 0)
|
||||
writeln("pidfd_open failed: ", strerror(errno).fromStringz);
|
||||
}
|
||||
|
@ -244,7 +275,27 @@ void onCloseWrite(FanotifyEvent ev)
|
|||
if (!getDevIno(ev.eventFd, key, ev.pid))
|
||||
return;
|
||||
if (auto ps = key in gMap)
|
||||
{
|
||||
ps.changed = true;
|
||||
|
||||
import sdiff;
|
||||
|
||||
const(ubyte)[] content;
|
||||
try
|
||||
{
|
||||
if (ps.filePathOpen.length)
|
||||
content = readAllFromFd(ev.eventFd);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
content = [];
|
||||
}
|
||||
|
||||
auto dataSource = new MMFile(ps.fileBytesSource);
|
||||
auto dataChange = new MMFile(content);
|
||||
|
||||
ps.fileBytesDiff = dataSource.diff(dataChange).slice();
|
||||
}
|
||||
}
|
||||
|
||||
void flushAndClearForPid(int pid, Epoll ep)
|
||||
|
@ -256,7 +307,10 @@ void flushAndClearForPid(int pid, Epoll ep)
|
|||
continue;
|
||||
auto s = gMap[k];
|
||||
if (s.changed)
|
||||
{
|
||||
logChange(s.procName, s.filePathOpen, s.uid, s.ruid);
|
||||
writeln(cast(string)s.fileBytesDiff);
|
||||
}
|
||||
gMap.remove(k);
|
||||
}
|
||||
if (auto p = pid in gPidfdByPid)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue