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