From: Sebastien Marie Subject: patch: fix last -d To: tech@openbsd.org Date: Tue, 06 Aug 2024 15:53:27 +0200 Hi, I recently discovered the -d option of last(1): -d date Specify the snapshot date and time. All users logged in at the snapshot date and time will be reported. This may be used with the -f option to derive the results from stored wtmp files. When this argument is provided, all other options except for -f and -n are ignored. [...] But I found some problems with the current code. First, my wtmp has the following content: $ last semarie ttyp1 192.168.92.26 Tue Aug 06 15:30 still logged in semarie : Tue Aug 06 12:10 - 12:10 (00:00) root ttyp1 192.168.92.26 Tue Aug 06 11:21 - 11:21 (00:00) reboot ~ Tue Aug 06 11:06 shutdown ~ Tue Aug 06 10:32 root ttyp3 192.168.92.26 Sun Aug 04 09:20 - 09:20 (00:00) root ttyp2 192.168.92.26 Thu Aug 01 16:26 - 16:26 (00:00) semarie : Thu Aug 01 08:59 - shutdown (5+01:33) reboot ~ Thu Aug 01 08:59 shutdown ~ Thu Aug 01 08:57 wtmp begins Thu Aug 1 08:57 2024 First problem, if no entries are found at the given date, it prints the wtmp statistics, and process others options (while man page says it will not). Found an entry: $ last -d 202408061531 semarie ttyp1 192.168.92.26 Tue Aug 06 15:30 still logged in $ No entries: $ last -d 190001010000 wtmp begins Thu Aug 1 08:57 2024 $ last -c -d 190001010000 Total time: 00:00 wtmp begins Thu Aug 1 08:57 2024 $ The following diff address the problem: diff /home/semarie/repos/openbsd/src commit - c1d8b5d1f7c3ae991e9dd5cff7857b1d133e73e8 path + /home/semarie/repos/openbsd/src blob - 68399226ce6b920a777507c1bd71865a9f1ced94 file + usr.bin/last/last.c --- usr.bin/last/last.c +++ usr.bin/last/last.c @@ -392,6 +391,8 @@ wtmp(void) } } close(wfd); + if (snaptime) + return; if (calculate) { if ((total / SECSPERDAY) > 0) { int days = (total / SECSPERDAY); After processing all entries, just returns if using snaptime (-d option). When an entry was found, it exited earler. $ last -d 190001010000 $ Secondly, last(1) badly process the 'shutdown' entries: $ last -d 202408061500 semarie : Thu Aug 01 08:59 - shutdown (5+01:33) $ At 15:00, the user was not connected, as the host shutdowns at 2024-08-06 10:32, and nobody was connected at 15:00. The following diff address the problem: diff /home/semarie/repos/openbsd/src commit - c1d8b5d1f7c3ae991e9dd5cff7857b1d133e73e8 path + /home/semarie/repos/openbsd/src blob - 68399226ce6b920a777507c1bd71865a9f1ced94 file + usr.bin/last/last.c --- usr.bin/last/last.c +++ usr.bin/last/last.c @@ -344,8 +344,7 @@ wtmp(void) */ if (bp->ut_name[0] && ((want(bp, YES)) || (bp->ut_time < snaptime && - (T->logout > snaptime || !T->logout || - T->logout < 0)))) { + (llabs(T->logout) > snaptime || !T->logout)))) { snapfound = 1; print_entry(bp); printf(" "); T->logout is negative when the entry is a shutdown entry. Currently, it doesn't look if the shutdown time is in the specified snaptime. So just compare with llabs(3) value. The code is a bit painful to read and follow, please review carefully this chunk. Comments or OK ? -- Sebastien Marie