From 1874af5c9c9c59b8e57af79d81a13615b1e61666 Mon Sep 17 00:00:00 2001 From: Werner Fink Date: Fri, 19 Feb 2010 15:51:36 +0000 Subject: [PATCH] * Add option -w to the last command to display the full user and domain names in the output. Patch from Petr Lautrbach. * Add a manual page for utmpdump as this tool is sometimes very useful even if not intended for normal use. * Use paths.h macros for wall * Change path "/etc/powerstatus" to "/var/run/powerstatus" --- doc/Changelog | 8 ++++++ man/last.1 | 6 +++-- man/utmpdump.1 | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/Makefile | 12 ++++++--- src/dowall.c | 27 +++++++++++++++------ src/last.c | 36 ++++++++++++++++----------- src/paths.h | 2 +- 7 files changed, 130 insertions(+), 27 deletions(-) create mode 100644 man/utmpdump.1 diff --git a/doc/Changelog b/doc/Changelog index 47886b0..c787be3 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,11 @@ + [ Werner Fink ] + * Add option -w to the last command to display the full user and + domain names in the output. Patch from Petr Lautrbach. + * Add a manual page for utmpdump as this tool is sometimes + very useful even if not intended for normal use. + * Use paths.h macros for wall + * Change path "/etc/powerstatus" to "/var/run/powerstatus" + sysvinit (2.88dsf) UNRELEASED; urgency=low [ Petter Reinholdtsen ] diff --git a/man/last.1 b/man/last.1 index 01b79b2..20655e6 100644 --- a/man/last.1 +++ b/man/last.1 @@ -29,7 +29,7 @@ last, lastb \- show listing of last logged in users .RB [ \-R ] .RB [ \-\fInum\fP ] .RB "[ \-\fBn\fP \fInum\fP ]" -.RB [ \-adFiox ] +.RB [ \-adFiowx ] .RB "[ \-\fBf\fP \fIfile\fP ]" .RB "[ \-\fBt\fP \fIYYYYMMDDHHMMSS\fP ]" .RI [ name... ] @@ -40,7 +40,7 @@ last, lastb \- show listing of last logged in users .RB [ \-\fInum\fP ] .RB "[ \-\fBn\fP \fInum\fP ]" .RB "[ \-\fBf\fP \fIfile\fP ]" -.RB [ \-adFiox ] +.RB [ \-adFiowx ] .RI [ name... ] .RI [ tty... ] .\"}}} @@ -95,6 +95,8 @@ This option is like \fB-d\fP in that it displays the IP number of the remote host, but it displays the IP number in numbers-and-dots notation. .IP \fB\-o\fP Read an old-type wtmp file (written by linux-libc5 applications). +.IP \fB\-w\fP +Display full user and domain names in the output. .IP \fB\-x\fP Display the system shutdown entries and run level changes. .\"}}} diff --git a/man/utmpdump.1 b/man/utmpdump.1 new file mode 100644 index 0000000..1b5730d --- /dev/null +++ b/man/utmpdump.1 @@ -0,0 +1,66 @@ +'\" -*- coding: UTF-8 -*- +.\" Copyright (C) 2010 Michael Krapp +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +.\" +.TH UTMPDUMP 1 "Februar 8, 2010" "" "Linux System Administrator's Manual" +.SH NAME +utmpdump \- dump UTMP and WTMP files in raw format +.SH SYNOPSIS +.B utmpdump +.RB [ \-froh ] +.I filename +.SH DESCRIPTION +\fButmpdump\fP is a simple program to dump UTMP and WTMP files +in raw format, so they can be examined. +.SH OPTIONS +.IP \fB\-f\fP +output appended data as the file grows. +.IP "\fB\-r\fP" +reverse. Write back edited login information into utmp or wtmp files. +.IP \fB\-o\fP +use old libc5 format. +.IP \fB\-h\fP +usage information. +.PP +utmpdump can be useful in cases of corrupted utmp or wtmp entries. +It can dump out utmp/wtmp to an ASCII file, then that file can +be edited to remove bogus entries and reintegrated, using +.PP +.sp 1 +.in +1c +.nf +\fButmpdump -r < ascii file > wtmp\fP +.fi +.in -1c +.sp 1 +but be warned as +.B utmpdump +was written for debugging purpose only. +.SH BUGS +You may +.B not +use the option \fB\-r\fP as the format for the +utmp/wtmp files strongly depends on the +input format. This tool was +.B not +written for normal use but for debugging. +.SH AUTHOR +Michael Krapp +.SH "SEE ALSO" +.BR last (1), +.BR w (1), +.BR who (1), +.BR utmp (5), diff --git a/src/Makefile b/src/Makefile index 6e0e962..a086198 100644 --- a/src/Makefile +++ b/src/Makefile @@ -26,7 +26,7 @@ ifeq ($(DISTRO),) BIN += mountpoint SBIN += sulogin bootlogd USRBIN += utmpdump wall -MAN1 += mountpoint.1 wall.1 +MAN1 += utmpdump.1 mountpoint.1 wall.1 MAN8 += sulogin.8 bootlogd.8 endif @@ -42,6 +42,14 @@ USRBIN += wall MAN1 += wall.1 endif +ifeq ($(DISTRO),SuSE) +BIN += mountpoint +SBIN += sulogin +USRBIN += utmpdump +MAN1 += utmpdump.1 mountpoint.1 +MAN8 += sulogin.8 +endif + BIN_OWNER = root BIN_GROUP = root BIN_COMBO = $(BIN_OWNER):$(BIN_GROUP) @@ -61,8 +69,6 @@ else SULOGIN_SELIBS= endif - - # Additional libs for GNU libc. ifneq ($(wildcard /usr/lib*/libcrypt.a),) LCRYPT = -lcrypt diff --git a/src/dowall.c b/src/dowall.c index 05684e0..826c59c 100644 --- a/src/dowall.c +++ b/src/dowall.c @@ -36,6 +36,14 @@ #include #include #include +#include + +#ifndef _PATH_DEV +# define _PATH_DEV "/dev/" +#endif +#ifndef HOST_NAME_MAX +# define HOST_NAME_MAX 255 +#endif static sigjmp_buf jbuf; @@ -88,9 +96,14 @@ static void getuidtty(char **userp, char **ttyp) } if ((tty = ttyname(0)) != NULL) { - if (strncmp(tty, "/dev/", 5) == 0) - tty += 5; - sprintf(ttynm, "(%.28s) ", tty); + const size_t plen = strlen(_PATH_DEV); + if (strncmp(tty, _PATH_DEV, plen) == 0) { + tty += plen; + if (tty[0] == '/') + tty++; + } + snprintf(ttynm, sizeof(ttynm), "(%.*s) ", + UT_LINESIZE, tty); } else ttynm[0] = 0; init++; @@ -138,9 +151,9 @@ void wall(const char *text, int remote) struct sigaction sa; struct utmp *utmp; time_t t; - char term[UT_LINESIZE+6]; + char term[UT_LINESIZE+ strlen(_PATH_DEV) + 1]; char line[81]; - char hostname[256]; /* HOST_NAME_MAX+1 */ + char hostname[HOST_NAME_MAX+1]; char *date, *p; char *user, *tty; int fd, flags; @@ -198,11 +211,11 @@ void wall(const char *text, int remote) while ((utmp = getutent()) != NULL) { if(utmp->ut_type != USER_PROCESS || utmp->ut_user[0] == 0) continue; - if (strncmp(utmp->ut_line, "/dev/", 5) == 0) { + if (strncmp(utmp->ut_line, _PATH_DEV, strlen(_PATH_DEV)) == 0) { term[0] = 0; strncat(term, utmp->ut_line, sizeof(term)-1); } else - snprintf(term, sizeof(term), "/dev/%.*s", + snprintf(term, sizeof(term), _PATH_DEV "%.*s", UT_LINESIZE, utmp->ut_line); if (strstr(term, "/../")) continue; diff --git a/src/last.c b/src/last.c index da91e82..5003c7c 100644 --- a/src/last.c +++ b/src/last.c @@ -80,6 +80,8 @@ int altlist = 0; /* Show hostname at the end. */ int usedns = 0; /* Use DNS to lookup the hostname. */ int useip = 0; /* Print IP address in number format */ int fulltime = 0; /* Print full dates and times */ +int name_len = 8; /* Default print 8 characters of name */ +int domain_len = 16; /* Default print 16 characters of domain */ int oldfmt = 0; /* Use old libc5 format? */ char **show = NULL; /* What do they want us to show */ char *ufile; /* Filename of this file */ @@ -368,7 +370,7 @@ int list(struct utmp *p, time_t t, int what) char logintime[32]; char logouttime[32]; char length[32]; - char final[128]; + char final[512]; char utline[UT_LINESIZE+1]; char domain[256]; char *s, **walk; @@ -478,24 +480,24 @@ int list(struct utmp *p, time_t t, int what) if (!altlist) { len = snprintf(final, sizeof(final), fulltime ? - "%-8.8s %-12.12s %-16.16s %-24.24s %-26.26s %-12.12s\n" : - "%-8.8s %-12.12s %-16.16s %-16.16s %-7.7s %-12.12s\n", - p->ut_name, utline, - domain, logintime, logouttime, length); + "%-8.*s %-12.12s %-16.*s %-24.24s %-26.26s %-12.12s\n" : + "%-8.*s %-12.12s %-16.*s %-16.16s %-7.7s %-12.12s\n", + name_len, p->ut_name, utline, + domain_len, domain, logintime, logouttime, length); } else { len = snprintf(final, sizeof(final), fulltime ? - "%-8.8s %-12.12s %-24.24s %-26.26s %-12.12s %s\n" : - "%-8.8s %-12.12s %-16.16s %-7.7s %-12.12s %s\n", - p->ut_name, utline, + "%-8.*s %-12.12s %-24.24s %-26.26s %-12.12s %s\n" : + "%-8.*s %-12.12s %-16.16s %-7.7s %-12.12s %s\n", + name_len, p->ut_name, utline, logintime, logouttime, length, domain); } } else len = snprintf(final, sizeof(final), fulltime ? - "%-8.8s %-12.12s %-24.24s %-26.26s %-12.12s\n" : - "%-8.8s %-12.12s %-16.16s %-7.7s %-12.12s\n", - p->ut_name, utline, + "%-8.*s %-12.12s %-24.24s %-26.26s %-12.12s\n" : + "%-8.*s %-12.12s %-16.16s %-7.7s %-12.12s\n", + name_len, p->ut_name, utline, logintime, logouttime, length); #if defined(__GLIBC__) @@ -514,7 +516,7 @@ int list(struct utmp *p, time_t t, int what) putchar('*'); } - if (len < 0 || len >= sizeof(final)) + if (len < 0 || (size_t)len >= sizeof(final)) putchar('\n'); recsdone++; @@ -532,7 +534,7 @@ void usage(char *s) { fprintf(stderr, "Usage: %s [-num | -n num] [-f file] " "[-t YYYYMMDDHHMMSS] " - "[-R] [-adioxF] [username..] [tty..]\n", s); + "[-R] [-adioxFw] [username..] [tty..]\n", s); exit(1); } @@ -603,7 +605,7 @@ int main(int argc, char **argv) progname = mybasename(argv[0]); /* Process the arguments. */ - while((c = getopt(argc, argv, "f:n:RxadFiot:0123456789")) != EOF) + while((c = getopt(argc, argv, "f:n:RxadFiot:0123456789w")) != EOF) switch(c) { case 'R': showhost = 0; @@ -644,6 +646,12 @@ int main(int argc, char **argv) usage(progname); } break; + case 'w': + if (UT_NAMESIZE > name_len) + name_len = UT_NAMESIZE; + if (UT_HOSTSIZE > domain_len) + domain_len = UT_HOSTSIZE; + break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': maxrecs = 10*maxrecs + c - '0'; diff --git a/src/paths.h b/src/paths.h index 884df35..bb5040d 100644 --- a/src/paths.h +++ b/src/paths.h @@ -35,7 +35,7 @@ #define SHELL "/bin/sh" /* Default shell */ #define SULOGIN "/sbin/sulogin" /* Sulogin */ #define INITSCRIPT "/etc/initscript" /* Initscript. */ -#define PWRSTAT "/etc/powerstatus" /* COMPAT: SIGPWR reason (OK/BAD) */ +#define PWRSTAT "/var/run/powerstatus" /* COMPAT: SIGPWR reason (OK/BAD) */ #if 0 #define INITLVL "/etc/initrunlvl" /* COMPAT: New runlevel */