blob: 113f850fed7f32c1100d25693da381cfcc432ffe [file] [log] [blame]
Erik Andersene49d5ec2000-02-08 19:58:47 +00001/* vi: set sw=4 ts=4: */
Eric Andersencc8ed391999-10-05 16:24:54 +00002/*
3 * public domain -- Dave 'Kill a Cop' Cinege <dcinege@psychosis.com>
4 *
5 * dutmp
6 * Takes utmp formated file on stdin and dumps it's contents
7 * out in colon delimited fields. Easy to 'cut' for shell based
8 * versions of 'who', 'last', etc. IP Addr is output in hex,
9 * little endian on x86.
10 *
Eric Andersencc8ed391999-10-05 16:24:54 +000011 */
Eric Andersen3cf52d11999-10-12 22:26:06 +000012
Manuel Novoa III cad53642003-03-19 09:13:01 +000013/* Mar 13, 2003 Manuel Novoa III
14 *
15 * 1) Added proper error checking.
16 * 2) Allow '-' arg for stdin.
17 * 3) For modern libcs, take into account that utmp char[] members
18 * need not be nul-terminated.
19 */
20
Eric Andersened3ef502001-01-27 08:24:39 +000021#include <stdlib.h>
22#include <unistd.h>
Manuel Novoa III cad53642003-03-19 09:13:01 +000023#include <fcntl.h>
24#include <utmp.h>
Eric Andersencbe31da2001-02-20 06:14:08 +000025#include "busybox.h"
Erik Andersen4f3f7572000-04-28 00:18:56 +000026
Manuel Novoa III cad53642003-03-19 09:13:01 +000027/* Grr... utmp char[] members do not have to be nul-terminated.
28 * Do what we can while still keeping this reasonably small.
29 * Note: We are assuming the ut_id[] size is fixed at 4. */
30
31#if __GNU_LIBRARY__ < 5
32#warning the format string needs to be changed
33#else
34#if (UT_LINESIZE != 32) || (UT_NAMESIZE != 32) || (UT_HOSTSIZE != 256)
35#error struct utmp member char[] size(s) have changed!
36#endif
37#endif
38
Erik Andersene49d5ec2000-02-08 19:58:47 +000039extern int dutmp_main(int argc, char **argv)
Eric Andersencc8ed391999-10-05 16:24:54 +000040{
Manuel Novoa III cad53642003-03-19 09:13:01 +000041 int file = STDIN_FILENO;
42 ssize_t n;
Erik Andersene49d5ec2000-02-08 19:58:47 +000043 struct utmp ut;
Eric Andersencc8ed391999-10-05 16:24:54 +000044
Manuel Novoa III cad53642003-03-19 09:13:01 +000045 if (argc > 2) {
46 bb_show_usage();
47 }
48 ++argv;
49 if ((argc == 2) && ((argv[0][0] != '-') || argv[0][1])) {
50 file = bb_xopen(*argv, O_RDONLY);
Erik Andersene49d5ec2000-02-08 19:58:47 +000051 }
Eric Andersencc8ed391999-10-05 16:24:54 +000052
Manuel Novoa III cad53642003-03-19 09:13:01 +000053
54 while ((n = safe_read(file, (void*)&ut, sizeof(struct utmp))) != 0) {
55
56 if (n != sizeof(struct utmp)) {
57 bb_perror_msg_and_die("short read");
58 }
59
60 /* Kludge around the fact that the binary format for utmp has changed. */
Eric Andersen8c4025e2002-07-03 05:32:02 +000061#if __GNU_LIBRARY__ < 5
Manuel Novoa III cad53642003-03-19 09:13:01 +000062 /* Linux libc5 */
63
64 bb_printf("%d|%d|%s|%s|%s|%s|%s|%lx\n",
65 ut.ut_type, ut.ut_pid, ut.ut_line,
66 ut.ut_id, ut.ut_user, ut.ut_host,
67 ctime(&(ut.ut_time)),
68 (long)ut.ut_addr);
Eric Andersen75610e12000-09-22 00:22:10 +000069#else
Manuel Novoa III cad53642003-03-19 09:13:01 +000070 /* Glibc, uClibc, etc. */
71
72 bb_printf("%d|%d|%.32s|%.4s|%.32s|%.256s|%d|%d|%ld|%ld|%ld|%x\n",
73 ut.ut_type, ut.ut_pid, ut.ut_line,
74 ut.ut_id, ut.ut_user, ut.ut_host,
75 ut.ut_exit.e_termination, ut.ut_exit.e_exit,
76 ut.ut_session,
77 ut.ut_tv.tv_sec, ut.ut_tv.tv_usec,
78 ut.ut_addr);
Eric Andersen75610e12000-09-22 00:22:10 +000079#endif
Manuel Novoa III cad53642003-03-19 09:13:01 +000080 }
81
82 bb_fflush_stdout_and_exit(EXIT_SUCCESS);
Eric Andersencc8ed391999-10-05 16:24:54 +000083}