filemon

Monitor what is modifiying your files

Files | Log | Commits | Refs | README


6d3f36c

Author: SM

Date: 2025-08-22

Subject: add name to UID

Diff

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