/* $NetBSD: getent.c,v 1.7 2005/08/24 14:31:02 ginsbach Exp $ */
/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
* Copyright (c) 2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
#include <net/if.h>
#include <netinet/if_ether.h>
#include <netinet/in.h> /* for INET6_ADDRSTRLEN */
-#include <rpc/rpcent.h>
#include <assert.h>
#include <ctype.h>
#include <limits.h>
#include <netdb.h>
#include <pwd.h>
-#include <stdio.h>
#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <utmpx.h>
+
+#include <arpa/nameser_compat.h>
+#include "utmpx-defines.h"
+int setutxdb(int db, const char *file);
static int usage(void);
static int parsenum(const char *, unsigned long *);
static int ethers(int, char *[]);
static int group(int, char *[]);
static int hosts(int, char *[]);
+static int netgroup(int, char *[]);
static int networks(int, char *[]);
static int passwd(int, char *[]);
static int protocols(int, char *[]);
static int rpc(int, char *[]);
static int services(int, char *[]);
static int shells(int, char *[]);
+static int utmpx(int, char *[]);
enum {
RV_OK = 0,
RV_USAGE = 1,
RV_NOTFOUND = 2,
- RV_NOENUM = 3,
+ RV_NOENUM = 3
};
static struct getentdb {
{ "ethers", ethers, },
{ "group", group, },
{ "hosts", hosts, },
+ { "netgroup", netgroup, },
{ "networks", networks, },
{ "passwd", passwd, },
{ "protocols", protocols, },
{ "rpc", rpc, },
{ "services", services, },
{ "shells", shells, },
+ { "utmpx", utmpx, },
{ NULL, NULL, },
};
for (curdb = databases; curdb->name != NULL; curdb++) {
if (strcmp(curdb->name, argv[1]) == 0) {
exit(curdb->callback(argc, argv));
- break;
}
}
fprintf(stderr, "Unknown database: %s\n", argv[1]);
curpref = sep;
}
printf("\n");
+ va_end(ap);
}
/*
static int
hosts(int argc, char *argv[])
{
- struct hostent *he;
+ struct hostent *he4, *he6;
char addr[IN6ADDRSZ];
int i, rv;
assert(argv != NULL);
sethostent(1);
+ he4 = he6 = NULL;
rv = RV_OK;
if (argc == 2) {
- while ((he = gethostent()) != NULL)
- hostsprint(he);
+ while ((he4 = gethostent()) != NULL)
+ hostsprint(he4);
} else {
for (i = 2; i < argc; i++) {
- if (inet_pton(AF_INET6, argv[i], (void *)addr) > 0)
- he = gethostbyaddr(addr, IN6ADDRSZ, AF_INET6);
- else if (inet_pton(AF_INET, argv[i], (void *)addr) > 0)
- he = gethostbyaddr(addr, INADDRSZ, AF_INET);
- else
- he = gethostbyname(argv[i]);
- if (he != NULL)
- hostsprint(he);
- else {
+ if (inet_pton(AF_INET6, argv[i], (void *)addr) > 0) {
+ he6 = gethostbyaddr(addr, IN6ADDRSZ, AF_INET6);
+ if (he6 != NULL)
+ hostsprint(he6);
+ } else if (inet_pton(AF_INET, argv[i],
+ (void *)addr) > 0) {
+ he4 = gethostbyaddr(addr, INADDRSZ, AF_INET);
+ if (he4 != NULL)
+ hostsprint(he4);
+ } else {
+ he6 = gethostbyname2(argv[i], AF_INET6);
+ if (he6 != NULL)
+ hostsprint(he6);
+ he4 = gethostbyname(argv[i]);
+ if (he4 != NULL)
+ hostsprint(he4);
+ }
+ if ( he4 == NULL && he6 == NULL ) {
rv = RV_NOTFOUND;
break;
}
endusershell();
return rv;
}
+
+/*
+ * netgroup
+ */
+static int
+netgroup(int argc, char *argv[])
+{
+ char *host, *user, *domain;
+ int first;
+ int rv, i;
+
+ assert(argc > 1);
+ assert(argv != NULL);
+
+#define NETGROUPPRINT(s) (((s) != NULL) ? (s) : "")
+
+ rv = RV_OK;
+ if (argc == 2) {
+ fprintf(stderr, "Enumeration not supported on netgroup\n");
+ rv = RV_NOENUM;
+ } else {
+ for (i = 2; i < argc; i++) {
+ setnetgrent(argv[i]);
+ first = 1;
+ while (getnetgrent(&host, &user, &domain) != 0) {
+ if (first) {
+ first = 0;
+ (void)fputs(argv[i], stdout);
+ }
+ (void)printf(" (%s,%s,%s)",
+ NETGROUPPRINT(host),
+ NETGROUPPRINT(user),
+ NETGROUPPRINT(domain));
+ }
+ if (!first)
+ (void)putchar('\n');
+ endnetgrent();
+ }
+ }
+ 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("[%jd.%06u -- %.24s] ",
+ (intmax_t)ut->ut_tv.tv_sec, (unsigned int)ut->ut_tv.tv_usec,
+ 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("\" pid=\"%d\" user=\"%s\" line=\"%s\" host=\"%s\"\n",
+ ut->ut_pid, ut->ut_user, ut->ut_line, ut->ut_host);
+ break;
+ case INIT_PROCESS:
+ printf("init process: id=\"");
+ UTMPXPRINTID;
+ printf("\" pid=\"%d\"\n", ut->ut_pid);
+ break;
+ case LOGIN_PROCESS:
+ printf("login process: id=\"");
+ UTMPXPRINTID;
+ printf("\" pid=\"%d\" user=\"%s\" line=\"%s\" host=\"%s\"\n",
+ ut->ut_pid, ut->ut_user, ut->ut_line, ut->ut_host);
+ break;
+ case DEAD_PROCESS:
+ printf("dead process: id=\"");
+ UTMPXPRINTID;
+ printf("\" pid=\"%d\"\n", ut->ut_pid);
+ break;
+ default:
+ printf("unknown record type %hu\n", ut->ut_type);
+ break;
+ }
+}
+
+static int
+utmpx(int argc, char *argv[])
+{
+ const struct utmpx *ut;
+ const char *file = NULL;
+ int rv = RV_OK, db = 0;
+
+ assert(argc > 1);
+ assert(argv != NULL);
+
+ if (argc == 3 || argc == 4) {
+ 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;
+ if (argc == 4)
+ file = argv[3];
+ } else {
+ rv = RV_USAGE;
+ }
+
+ if (rv == RV_USAGE) {
+ fprintf(stderr,
+ "Usage: %s utmpx active | lastlogin | log [filename]\n",
+ getprogname());
+ } else if (rv == RV_OK) {
+ if (setutxdb(db, file) != 0)
+ return (RV_NOTFOUND);
+ while ((ut = getutxent()) != NULL)
+ utmpxprint(ut);
+ endutxent();
+ }
+ return (rv);
+}