Allow getent(1) to display utmpx entries as well.
Because getutxent also matches the typical get*ent format of library routines, I thought it would be a good idea to teach it how to read utmpx databases. getent(1) just gives a raw dump, which is very useful when debugging problems related to parsing/logging.
This commit is contained in:
parent
561f61e25d
commit
86586473e3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=202198
@ -75,6 +75,7 @@ argument may be one of:
|
|||||||
.It Li rpc Ta name number [alias ...]
|
.It Li rpc Ta name number [alias ...]
|
||||||
.It Li services Ta name port/protocol [alias ...]
|
.It Li services Ta name port/protocol [alias ...]
|
||||||
.It Li shells Ta /path/to/shell
|
.It Li shells Ta /path/to/shell
|
||||||
|
.It Li utmpx Ta [time] type: properties
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
If one or more
|
If one or more
|
||||||
@ -109,6 +110,7 @@ utility exits 0 on success,
|
|||||||
or 3 if there is no support for enumeration on
|
or 3 if there is no support for enumeration on
|
||||||
.Ar database .
|
.Ar database .
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
|
.Xr getutxent 3 ,
|
||||||
.Xr ethers 5 ,
|
.Xr ethers 5 ,
|
||||||
.Xr group 5 ,
|
.Xr group 5 ,
|
||||||
.Xr hosts 5 ,
|
.Xr hosts 5 ,
|
||||||
|
@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <utmpx.h>
|
||||||
|
|
||||||
static int usage(void);
|
static int usage(void);
|
||||||
static int parsenum(const char *, unsigned long *);
|
static int parsenum(const char *, unsigned long *);
|
||||||
@ -72,6 +73,7 @@ static int protocols(int, char *[]);
|
|||||||
static int rpc(int, char *[]);
|
static int rpc(int, char *[]);
|
||||||
static int services(int, char *[]);
|
static int services(int, char *[]);
|
||||||
static int shells(int, char *[]);
|
static int shells(int, char *[]);
|
||||||
|
static int utmpx(int, char *[]);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
RV_OK = 0,
|
RV_OK = 0,
|
||||||
@ -93,6 +95,7 @@ static struct getentdb {
|
|||||||
{ "rpc", rpc, },
|
{ "rpc", rpc, },
|
||||||
{ "services", services, },
|
{ "services", services, },
|
||||||
{ "shells", shells, },
|
{ "shells", shells, },
|
||||||
|
{ "utmpx", utmpx, },
|
||||||
|
|
||||||
{ NULL, NULL, },
|
{ NULL, NULL, },
|
||||||
};
|
};
|
||||||
@ -562,3 +565,89 @@ shells(int argc, char *argv[])
|
|||||||
endusershell();
|
endusershell();
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* utmpx
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define UTMPXPRINTID do { \
|
||||||
|
size_t i; \
|
||||||
|
for (i = 0; i < sizeof ut->ut_id; i++) \
|
||||||
|
printf("%02hhx", ut->ut_id[i]); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static void
|
||||||
|
utmpxprint(const struct utmpx *ut)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (ut->ut_type == EMPTY)
|
||||||
|
return;
|
||||||
|
|
||||||
|
printf("[%.24s] ", ctime(&ut->ut_tv.tv_sec));
|
||||||
|
|
||||||
|
switch (ut->ut_type) {
|
||||||
|
case BOOT_TIME:
|
||||||
|
printf("system boot\n");
|
||||||
|
return;
|
||||||
|
case SHUTDOWN_TIME:
|
||||||
|
printf("system shutdown\n");
|
||||||
|
return;
|
||||||
|
case OLD_TIME:
|
||||||
|
printf("old system time\n");
|
||||||
|
return;
|
||||||
|
case NEW_TIME:
|
||||||
|
printf("new system time\n");
|
||||||
|
return;
|
||||||
|
case USER_PROCESS:
|
||||||
|
printf("user process: id=\"");
|
||||||
|
UTMPXPRINTID;
|
||||||
|
printf("\" user=\"%s\" line=\"%s\" host=\"%s\"\n",
|
||||||
|
ut->ut_user, ut->ut_line, ut->ut_host);
|
||||||
|
break;
|
||||||
|
case DEAD_PROCESS:
|
||||||
|
printf("dead process: id=\"");
|
||||||
|
UTMPXPRINTID;
|
||||||
|
printf("\"\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("unknown record type\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
utmpx(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
const struct utmpx *ut;
|
||||||
|
int rv = RV_OK, db;
|
||||||
|
|
||||||
|
assert(argc > 1);
|
||||||
|
assert(argv != NULL);
|
||||||
|
|
||||||
|
if (argc == 2) {
|
||||||
|
db = UTXDB_ACTIVE;
|
||||||
|
} else if (argc == 3) {
|
||||||
|
if (strcmp(argv[2], "active") == 0)
|
||||||
|
db = UTXDB_ACTIVE;
|
||||||
|
else if (strcmp(argv[2], "lastlogin") == 0)
|
||||||
|
db = UTXDB_LASTLOGIN;
|
||||||
|
else if (strcmp(argv[2], "log") == 0)
|
||||||
|
db = UTXDB_LOG;
|
||||||
|
else
|
||||||
|
rv = RV_USAGE;
|
||||||
|
} else {
|
||||||
|
rv = RV_USAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rv == RV_USAGE) {
|
||||||
|
fprintf(stderr, "Usage: %s utmpx [active | lastlogin | log]\n",
|
||||||
|
getprogname());
|
||||||
|
} else if (rv == RV_OK) {
|
||||||
|
if (setutxdb(db, NULL) != 0)
|
||||||
|
return (RV_NOTFOUND);
|
||||||
|
while ((ut = getutxent()) != NULL)
|
||||||
|
utmpxprint(ut);
|
||||||
|
endutxent();
|
||||||
|
}
|
||||||
|
return (rv);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user