Monitor what is modifiying your files
Files | Log | Commits | Refs | README
Author: SM
Date: 2025-08-22
Subject: add name to UID
commit 6d3f36c4bc18c07e0fe52a2e7d0cd3df40b05aca
Author: SM <seb.michalk@gmail.com>
Date: Fri Aug 22 16:51:36 2025 +0200
add name to UID
diff --git a/Makefile b/Makefile
index f07438c..11e02af 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
CC = gcc
CFLAGS = -std=c99 -Wall -Wextra -O2 -D_POSIX_C_SOURCE=200809L
TARGET = who
-SOURCES = main.c proc.c
+SOURCES = main.c proc.c uid.c
.PHONY: all clean install
diff --git a/main.c b/main.c
index d20dda0..4241c6c 100644
--- a/main.c
+++ b/main.c
@@ -29,6 +29,7 @@
#include <linux/netlink.h>
#include "proc.h"
+#include "uid.h"
#define MAX_EVENTS 10
#define MAX_PROCS 1024
@@ -99,75 +100,6 @@ usage(void)
die("usage: who [-o output] directory\n");
}
-int
-main(int argc, char *argv[])
-{
- const char *outpath;
- int opt, nfds;
- struct epoll_event events[MAX_EVENTS];
-
- outpath = "who.log";
-
- while ((opt = getopt(argc, argv, "o:")) != -1) {
- switch (opt) {
- case 'o':
- outpath = optarg;
- break;
- default:
- usage();
- }
- }
-
- if (optind >= argc)
- usage();
-
- if (strlen(argv[optind]) >= MAX_PATH)
- die("directory path too long");
-
- strcpy(dir, argv[optind]);
-
- signal(SIGINT, sighandler);
- signal(SIGTERM, sighandler);
-
- out = fopen(outpath, "w");
- if (!out)
- die("fopen %s:", outpath);
-
- efd = epoll_create1(EPOLL_CLOEXEC);
- if (efd == -1)
- die("epoll_create1:");
-
- nlfd = initnetlink();
- ifd = initinotify(dir);
-
- scanprocs();
-
- state = STATE_MONITORING;
- fprintf(out, "# Who - started monitoring %s\n", dir);
- fprintf(out, "# Active processes: %d\n", nprocs);
- fflush(out);
-
- while (state == STATE_MONITORING) {
- nfds = epoll_wait(efd, events, MAX_EVENTS, -1);
- if (nfds == -1) {
- if (errno == EINTR)
- continue;
- die("epoll_wait:");
- }
-
- for (int i = 0; i < nfds; i++) {
- if (events[i].data.fd == nlfd) {
- handleproc();
- } else if (events[i].data.fd == ifd) {
- handlefile();
- }
- }
- }
-
- cleanup();
- return 0;
-}
-
static void
sighandler(int sig)
{
@@ -180,7 +112,7 @@ initnetlink(void)
{
struct sockaddr_nl sa_nl;
struct epoll_event ev;
- int sock;
+ int sock, bufsize = 65536;
sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
if (sock == -1)
@@ -194,8 +126,6 @@ initnetlink(void)
if (bind(sock, (struct sockaddr *)&sa_nl, sizeof(sa_nl)) == -1)
die("bind:");
- /* Increase socket buffer size */
- int bufsize = 65536;
if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) == -1)
die("setsockopt:");
@@ -533,11 +463,11 @@ logchange(const char *path, Process *proc, uint32_t mask)
strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S", tm);
if (proc) {
- fprintf(out, "%s %s %s pid=%d uid=%d gid=%d comm=%s cwd=%s\n",
+ fprintf(out, "%s %s %s pid=%d user=%s gid=%d comm=%s cwd=%s\n",
ts, maskstr(mask), path,
- proc->pid, proc->uid, proc->gid, proc->comm, proc->cwd);
+ proc->pid, uidname(proc->uid), proc->gid, proc->comm, proc->cwd);
} else {
- fprintf(out, "%s %s %s pid=? uid=? gid=? comm=? cwd=?\n",
+ fprintf(out, "%s %s %s pid=? user=? gid=? comm=? cwd=?\n",
ts, maskstr(mask), path);
}
@@ -581,3 +511,73 @@ scanprocs(void)
closedir(proc_dir);
}
+
+int
+main(int argc, char *argv[])
+{
+ const char *outpath;
+ int opt, nfds;
+ struct epoll_event events[MAX_EVENTS];
+
+ outpath = "who.log";
+
+ while ((opt = getopt(argc, argv, "o:")) != -1) {
+ switch (opt) {
+ case 'o':
+ outpath = optarg;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ if (optind >= argc)
+ usage();
+
+ if (strlen(argv[optind]) >= MAX_PATH)
+ die("directory path too long");
+
+ strcpy(dir, argv[optind]);
+
+ signal(SIGINT, sighandler);
+ signal(SIGTERM, sighandler);
+
+ out = fopen(outpath, "w");
+ if (!out)
+ die("fopen %s:", outpath);
+
+ efd = epoll_create1(EPOLL_CLOEXEC);
+ if (efd == -1)
+ die("epoll_create1:");
+
+ nlfd = initnetlink();
+ ifd = initinotify(dir);
+
+ uidinit();
+ scanprocs();
+
+ state = STATE_MONITORING;
+ fprintf(out, "# Who - started monitoring %s\n", dir);
+ fprintf(out, "# Active processes: %d\n", nprocs);
+ fflush(out);
+
+ while (state == STATE_MONITORING) {
+ nfds = epoll_wait(efd, events, MAX_EVENTS, -1);
+ if (nfds == -1) {
+ if (errno == EINTR)
+ continue;
+ die("epoll_wait:");
+ }
+
+ for (int i = 0; i < nfds; i++) {
+ if (events[i].data.fd == nlfd) {
+ handleproc();
+ } else if (events[i].data.fd == ifd) {
+ handlefile();
+ }
+ }
+ }
+
+ cleanup();
+ return 0;
+}
diff --git a/uid.c b/uid.c
new file mode 100644
index 0000000..368333e
--- /dev/null
+++ b/uid.c
@@ -0,0 +1,81 @@
+/* See LICENSE file for copyright and license details. */
+
+#define _POSIX_C_SOURCE 200809L
+
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "uid.h"
+
+struct uidentry {
+ struct uidentry *next;
+ uid_t uid;
+ char *name;
+};
+
+#define HASHSIZE 101
+static struct uidentry *hashtab[HASHSIZE];
+
+static unsigned
+hash(uid_t uid)
+{
+ return uid % HASHSIZE;
+}
+
+
+static struct uidentry *
+lookup(uid_t uid)
+{
+ struct uidentry *np;
+
+ for (np = hashtab[hash(uid)]; np; np = np->next)
+ if (np->uid == uid)
+ return np;
+ return NULL;
+}
+
+static struct uidentry *
+install(uid_t uid, const char *name)
+{
+ struct uidentry *np;
+ unsigned hashval;
+
+ if ((np = lookup(uid)) == NULL) {
+ np = malloc(sizeof(*np));
+ if (!np || !(np->name = strdup(name)))
+ return NULL;
+ np->uid = uid;
+ hashval = hash(uid);
+ np->next = hashtab[hashval];
+ hashtab[hashval] = np;
+ }
+ return np;
+}
+
+void
+uidinit(void)
+{
+ int i;
+
+ for (i = 0; i < HASHSIZE; i++)
+ hashtab[i] = NULL;
+}
+
+const char *
+uidname(uid_t uid)
+{
+ struct uidentry *entry;
+ struct passwd *pw;
+
+ if ((entry = lookup(uid)))
+ return entry->name;
+
+ if ((pw = getpwuid(uid))) {
+ install(uid, pw->pw_name);
+ return lookup(uid)->name;
+ }
+
+ return "unknown";
+}
diff --git a/uid.h b/uid.h
new file mode 100644
index 0000000..9d04ddd
--- /dev/null
+++ b/uid.h
@@ -0,0 +1,11 @@
+/* See LICENSE file for copyright and license details. */
+
+#ifndef UID_H
+#define UID_H
+
+#include <sys/types.h>
+
+void uidinit(void);
+const char *uidname(uid_t uid);
+
+#endif