Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/who add utmpx support; lots of code can be shared no...
details: https://anonhg.NetBSD.org/src/rev/b097efb9ec90
branches: trunk
changeset: 534511:b097efb9ec90
user: christos <christos%NetBSD.org@localhost>
date: Sun Jul 28 21:46:34 2002 +0000
description:
add utmpx support; lots of code can be shared now with w.
diffstat:
usr.bin/who/Makefile | 3 +-
usr.bin/who/who.c | 327 ++++++++++++++++++++++++++++++++++++++------------
2 files changed, 249 insertions(+), 81 deletions(-)
diffs (truncated from 456 to 300 lines):
diff -r 9f4cd52521b4 -r b097efb9ec90 usr.bin/who/Makefile
--- a/usr.bin/who/Makefile Sun Jul 28 21:45:39 2002 +0000
+++ b/usr.bin/who/Makefile Sun Jul 28 21:46:34 2002 +0000
@@ -1,6 +1,7 @@
-# $NetBSD: Makefile,v 1.5 1997/10/20 03:20:27 lukem Exp $
+# $NetBSD: Makefile,v 1.6 2002/07/28 21:46:34 christos Exp $
# @(#)Makefile 8.1 (Berkeley) 6/6/93
PROG= who
+CPPFLAGS+= -DSUPPORT_UTMPX -DSUPPORT_UTMP
.include <bsd.prog.mk>
diff -r 9f4cd52521b4 -r b097efb9ec90 usr.bin/who/who.c
--- a/usr.bin/who/who.c Sun Jul 28 21:45:39 2002 +0000
+++ b/usr.bin/who/who.c Sun Jul 28 21:46:34 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: who.c,v 1.8 1999/07/17 16:41:44 christos Exp $ */
+/* $NetBSD: who.c,v 1.9 2002/07/28 21:46:34 christos Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -47,7 +47,7 @@
#if 0
static char sccsid[] = "@(#)who.c 8.1 (Berkeley) 6/6/93";
#endif
-__RCSID("$NetBSD: who.c,v 1.8 1999/07/17 16:41:44 christos Exp $");
+__RCSID("$NetBSD: who.c,v 1.9 2002/07/28 21:46:34 christos Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -60,26 +60,47 @@
#include <string.h>
#include <time.h>
#include <unistd.h>
+#ifdef SUPPORT_UTMP
#include <utmp.h>
+#endif
+#ifdef SUPPORT_UTMPX
+#include <utmpx.h>
+#endif
+
+struct entry {
+ char name[65];
+ char line[65];
+ char host[257];
+ time_t time;
+ struct entry *next;
+};
-void output __P((struct utmp *));
-void output_labels __P((void));
-void who_am_i __P((FILE *));
-FILE *file __P((char *));
-void usage __P((void));
+static void output_labels(void);
+static void who_am_i(const char *, int);
+static void usage(void);
+static void process(const char *, int);
+#ifdef SUPPORT_UTMP
+static void getentry(struct entry *, struct utmp *);
+#endif
+#ifdef SUPPORT_UTMPX
+static void getentryx(struct entry *, struct utmpx *);
+#endif
+#if defined(SUPPORT_UTMPX) && defined(SUPPORT_UTMP)
+static int setup(const char *);
+static void adjust_size(struct entry *e);
+#endif
+static void print(const char *, const char *, time_t, const char *);
-int show_term; /* show term state */
-int show_idle; /* show idle time */
+int main(int, char **);
-int main __P((int, char **));
+static int show_term; /* show term state */
+static int show_idle; /* show idle time */
+
+static int maxname = 8, maxline = 8, maxhost = 16;
int
-main(argc, argv)
- int argc;
- char **argv;
+main(int argc, char **argv)
{
- struct utmp usr;
- FILE *ufp;
int c, only_current_term, show_labels;
setlocale(LC_ALL, "");
@@ -112,36 +133,23 @@
/* NOTREACHED */
}
- if (show_labels)
- output_labels();
-
switch (argc) {
case 0: /* who */
- ufp = file(_PATH_UTMP);
-
if (only_current_term) {
- who_am_i(ufp);
+ who_am_i(NULL, show_labels);
} else {
- /* only entries with both name and line fields */
- while (fread((char *)&usr, sizeof(usr), 1, ufp) == 1)
- if (*usr.ut_name && *usr.ut_line)
- output(&usr);
+ process(NULL, show_labels);
}
break;
case 1: /* who utmp_file */
- ufp = file(*argv);
-
if (only_current_term) {
- who_am_i(ufp);
+ who_am_i(*argv, show_labels);
} else {
- /* all entries */
- while (fread((char *)&usr, sizeof(usr), 1, ufp) == 1)
- output(&usr);
+ process(*argv, show_labels);
}
break;
case 2: /* who am i */
- ufp = file(_PATH_UTMP);
- who_am_i(ufp);
+ who_am_i(NULL, show_labels);
break;
default:
usage();
@@ -150,44 +158,218 @@
exit(0);
}
-void
-who_am_i(ufp)
- FILE *ufp;
+#if defined(SUPPORT_UTMPX) && defined(SUPPORT_UTMP)
+static void
+adjust_size(struct entry *e)
+{
+ int max;
+
+ if ((max = strlen(e->name)) > maxname)
+ maxname = max;
+ if ((max = strlen(e->line)) > maxline)
+ maxline = max;
+ if ((max = strlen(e->host)) > maxhost)
+ maxhost = max;
+}
+
+static int
+setup(const char *fname)
{
- struct utmp usr;
+ int what = 3;
+
+ if (fname == NULL) {
+#ifdef SUPPORT_UTMPX
+ setutent();
+#endif
+#ifdef SUPPORT_UTMP
+ setutxent();
+#endif
+ } else {
+ size_t len = strlen(fname);
+ if (len == 0)
+ errx(1, "Filename cannot be 0 length.");
+ what = fname[len - 1] == 'x' ? 1 : 2;
+ if (what == 1) {
+#ifdef SUPPORT_UTMPX
+ if (utmpxname(fname) == 0)
+ err(1, "Cannot open `%s'", fname);
+#else
+ errx(1, "utmpx support not compiled in");
+#endif
+ } else {
+#ifdef SUPPORT_UTMPX
+ if (utmpname(fname) == 0)
+ err(1, "Cannot open `%s'", fname);
+#else
+ errx(1, "utmp support not compiled in");
+#endif
+ }
+ }
+ return what;
+}
+#endif
+
+static void
+who_am_i(const char *fname, int show_labels)
+{
+#ifdef SUPPORT_UTMPX
+ struct utmpx *utx;
+#endif
+#ifdef SUPPORT_UTMP
+ struct utmp *ut;
+#endif
struct passwd *pw;
char *p;
char *t;
+ time_t now;
+#if defined(SUPPORT_UTMP) && defined(SUPPORT_UTMPX)
+ int what = setup(fname);
+#endif
/* search through the utmp and find an entry for this tty */
- if ((p = ttyname(0)) != NULL) {
+ if ((p = ttyname(STDIN_FILENO)) != NULL) {
+
/* strip any directory component */
if ((t = strrchr(p, '/')) != NULL)
p = t + 1;
- while (fread((char *)&usr, sizeof(usr), 1, ufp) == 1)
- if (usr.ut_name[0] != '\0' &&
- !strcmp(usr.ut_line, p)) {
- output(&usr);
+#ifdef SUPPORT_UTMPX
+ while ((what & 1) && (utx = getutxent()) != NULL)
+ if (utx->ut_type == USER_PROCESS &&
+ !strcmp(utx->ut_line, p)) {
+ struct entry e;
+ getentryx(&e, utx);
+ if (show_labels)
+ output_labels();
+ print(e.name, e.line, e.time, e.host);
+ return;
+ }
+#endif
+#ifdef SUPPORT_UTMP
+ while ((what & 2) && (ut = getutent()) != NULL)
+ if (!strcmp(ut->ut_line, p)) {
+ struct entry e;
+ getentry(&e, ut);
+ if (show_labels)
+ output_labels();
+ print(e.name, e.line, e.time, e.host);
return;
}
- /* well, at least we know what the tty is */
- (void)strncpy(usr.ut_line, p, UT_LINESIZE);
+#endif
} else
- (void)strcpy(usr.ut_line, "tty??");
+ p = "tty??";
+ (void)time(&now);
pw = getpwuid(getuid());
- (void)strncpy(usr.ut_name, pw ? pw->pw_name : "?", UT_NAMESIZE);
- (void)time(&usr.ut_time);
- *usr.ut_host = '\0';
- output(&usr);
+ if (show_labels)
+ output_labels();
+ print(pw ? pw->pw_name : "?", p, now, "");
}
-void
-output(up)
- struct utmp *up;
+static void
+process(const char *fname, int show_labels)
+{
+#ifdef SUPPORT_UTMPX
+ struct utmpx *utx;
+#endif
+#ifdef SUPPORT_UTMP
+ struct utmp *ut;
+#endif
+ struct entry *ep, *ehead = NULL;
+#if defined(SUPPORT_UTMP) && defined(SUPPORT_UTMPX)
+ int what = setup(fname);
+ struct entry **nextp = &ehead;
+#endif
+
+#ifdef SUPPORT_UTMPX
+ while ((what & 1) && (utx = getutxent()) != NULL) {
+ if (fname == NULL && utx->ut_type != USER_PROCESS)
+ continue;
+ if ((ep = calloc(1, sizeof(struct entry))) == NULL)
+ err(1, NULL);
+ getentryx(ep, utx);
+ *nextp = ep;
+ nextp = &(ep->next);
+ }
+#endif
+
+#ifdef SUPPORT_UTMP
+ while ((what & 2) && (ut = getutent()) != NULL) {
+ if (fname == NULL && (*ut->ut_name == '\0' ||
+ *ut->ut_line == '\0'))
+ continue;
+ /* Don't process entries that we have utmpx for */
+ for (ep = ehead; ep != NULL; ep = ep->next) {
+ if (strncmp(ep->line, ut->ut_line,
+ sizeof(ut->ut_line)) == 0)
+ break;
Home |
Main Index |
Thread Index |
Old Index