busybox/miscutils/dutmp.c
2003-03-19 09:13:01 +00:00

84 lines
2.1 KiB
C

/* vi: set sw=4 ts=4: */
/*
* public domain -- Dave 'Kill a Cop' Cinege <dcinege@psychosis.com>
*
* dutmp
* Takes utmp formated file on stdin and dumps it's contents
* out in colon delimited fields. Easy to 'cut' for shell based
* versions of 'who', 'last', etc. IP Addr is output in hex,
* little endian on x86.
*
*/
/* Mar 13, 2003 Manuel Novoa III
*
* 1) Added proper error checking.
* 2) Allow '-' arg for stdin.
* 3) For modern libcs, take into account that utmp char[] members
* need not be nul-terminated.
*/
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <utmp.h>
#include "busybox.h"
/* Grr... utmp char[] members do not have to be nul-terminated.
* Do what we can while still keeping this reasonably small.
* Note: We are assuming the ut_id[] size is fixed at 4. */
#if __GNU_LIBRARY__ < 5
#warning the format string needs to be changed
#else
#if (UT_LINESIZE != 32) || (UT_NAMESIZE != 32) || (UT_HOSTSIZE != 256)
#error struct utmp member char[] size(s) have changed!
#endif
#endif
extern int dutmp_main(int argc, char **argv)
{
int file = STDIN_FILENO;
ssize_t n;
struct utmp ut;
if (argc > 2) {
bb_show_usage();
}
++argv;
if ((argc == 2) && ((argv[0][0] != '-') || argv[0][1])) {
file = bb_xopen(*argv, O_RDONLY);
}
while ((n = safe_read(file, (void*)&ut, sizeof(struct utmp))) != 0) {
if (n != sizeof(struct utmp)) {
bb_perror_msg_and_die("short read");
}
/* Kludge around the fact that the binary format for utmp has changed. */
#if __GNU_LIBRARY__ < 5
/* Linux libc5 */
bb_printf("%d|%d|%s|%s|%s|%s|%s|%lx\n",
ut.ut_type, ut.ut_pid, ut.ut_line,
ut.ut_id, ut.ut_user, ut.ut_host,
ctime(&(ut.ut_time)),
(long)ut.ut_addr);
#else
/* Glibc, uClibc, etc. */
bb_printf("%d|%d|%.32s|%.4s|%.32s|%.256s|%d|%d|%ld|%ld|%ld|%x\n",
ut.ut_type, ut.ut_pid, ut.ut_line,
ut.ut_id, ut.ut_user, ut.ut_host,
ut.ut_exit.e_termination, ut.ut_exit.e_exit,
ut.ut_session,
ut.ut_tv.tv_sec, ut.ut_tv.tv_usec,
ut.ut_addr);
#endif
}
bb_fflush_stdout_and_exit(EXIT_SUCCESS);
}