xref: /dflybsd-src/usr.bin/getent/getent.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1*86d7f5d3SJohn Marino /*-
2*86d7f5d3SJohn Marino  * Copyright (c) 2004 The NetBSD Foundation, Inc.
3*86d7f5d3SJohn Marino  * All rights reserved.
4*86d7f5d3SJohn Marino  *
5*86d7f5d3SJohn Marino  * This code is derived from software contributed to The NetBSD Foundation
6*86d7f5d3SJohn Marino  * by Luke Mewburn.
7*86d7f5d3SJohn Marino  *
8*86d7f5d3SJohn Marino  * Redistribution and use in source and binary forms, with or without
9*86d7f5d3SJohn Marino  * modification, are permitted provided that the following conditions
10*86d7f5d3SJohn Marino  * are met:
11*86d7f5d3SJohn Marino  * 1. Redistributions of source code must retain the above copyright
12*86d7f5d3SJohn Marino  *    notice, this list of conditions and the following disclaimer.
13*86d7f5d3SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
14*86d7f5d3SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
15*86d7f5d3SJohn Marino  *    documentation and/or other materials provided with the distribution.
16*86d7f5d3SJohn Marino  * 3. All advertising materials mentioning features or use of this software
17*86d7f5d3SJohn Marino  *    must display the following acknowledgement:
18*86d7f5d3SJohn Marino  *	This product includes software developed by the NetBSD
19*86d7f5d3SJohn Marino  *	Foundation, Inc. and its contributors.
20*86d7f5d3SJohn Marino  * 4. Neither the name of The NetBSD Foundation nor the names of its
21*86d7f5d3SJohn Marino  *    contributors may be used to endorse or promote products derived
22*86d7f5d3SJohn Marino  *    from this software without specific prior written permission.
23*86d7f5d3SJohn Marino  *
24*86d7f5d3SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
25*86d7f5d3SJohn Marino  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26*86d7f5d3SJohn Marino  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27*86d7f5d3SJohn Marino  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
28*86d7f5d3SJohn Marino  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29*86d7f5d3SJohn Marino  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30*86d7f5d3SJohn Marino  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31*86d7f5d3SJohn Marino  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32*86d7f5d3SJohn Marino  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33*86d7f5d3SJohn Marino  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34*86d7f5d3SJohn Marino  * POSSIBILITY OF SUCH DAMAGE.
35*86d7f5d3SJohn Marino  *
36*86d7f5d3SJohn Marino  * $NetBSD: getent.c,v 1.7 2005/08/24 14:31:02 ginsbach Exp $
37*86d7f5d3SJohn Marino  * $DragonFly: src/usr.bin/getent/getent.c,v 1.1 2007/12/04 18:13:09 dillon Exp $
38*86d7f5d3SJohn Marino  */
39*86d7f5d3SJohn Marino 
40*86d7f5d3SJohn Marino #include <sys/socket.h>
41*86d7f5d3SJohn Marino #include <sys/param.h>
42*86d7f5d3SJohn Marino #include <arpa/inet.h>
43*86d7f5d3SJohn Marino #include <arpa/nameser.h>
44*86d7f5d3SJohn Marino #include <net/if.h>
45*86d7f5d3SJohn Marino #include <netinet/if_ether.h>
46*86d7f5d3SJohn Marino #include <netinet/in.h>		/* for INET6_ADDRSTRLEN */
47*86d7f5d3SJohn Marino #include <rpc/rpc.h>
48*86d7f5d3SJohn Marino 
49*86d7f5d3SJohn Marino #include <assert.h>
50*86d7f5d3SJohn Marino #include <ctype.h>
51*86d7f5d3SJohn Marino #include <errno.h>
52*86d7f5d3SJohn Marino #include <grp.h>
53*86d7f5d3SJohn Marino #include <limits.h>
54*86d7f5d3SJohn Marino #include <netdb.h>
55*86d7f5d3SJohn Marino #include <pwd.h>
56*86d7f5d3SJohn Marino #include <stdio.h>
57*86d7f5d3SJohn Marino #include <stdarg.h>
58*86d7f5d3SJohn Marino #include <stdlib.h>
59*86d7f5d3SJohn Marino #include <string.h>
60*86d7f5d3SJohn Marino #include <unistd.h>
61*86d7f5d3SJohn Marino 
62*86d7f5d3SJohn Marino static int	usage(void);
63*86d7f5d3SJohn Marino static int	parsenum(const char *, unsigned long *);
64*86d7f5d3SJohn Marino static void	printfmtstrings(char **, const char *, const char *,
65*86d7f5d3SJohn Marino 		    const char *fmt, ...) __printflike(4, 5);
66*86d7f5d3SJohn Marino static int	ethers(int, char *[]);
67*86d7f5d3SJohn Marino static int	group(int, char *[]);
68*86d7f5d3SJohn Marino static int	hosts(int, char *[]);
69*86d7f5d3SJohn Marino static int	networks(int, char *[]);
70*86d7f5d3SJohn Marino static int	passwd(int, char *[]);
71*86d7f5d3SJohn Marino static int	protocols(int, char *[]);
72*86d7f5d3SJohn Marino static int	rpc(int, char *[]);
73*86d7f5d3SJohn Marino static int	services(int, char *[]);
74*86d7f5d3SJohn Marino static int	shells(int, char *[]);
75*86d7f5d3SJohn Marino 
76*86d7f5d3SJohn Marino enum {
77*86d7f5d3SJohn Marino 	RV_OK		= 0,
78*86d7f5d3SJohn Marino 	RV_USAGE	= 1,
79*86d7f5d3SJohn Marino 	RV_NOTFOUND	= 2,
80*86d7f5d3SJohn Marino 	RV_NOENUM	= 3
81*86d7f5d3SJohn Marino };
82*86d7f5d3SJohn Marino 
83*86d7f5d3SJohn Marino static struct getentdb {
84*86d7f5d3SJohn Marino 	const char	*name;
85*86d7f5d3SJohn Marino 	int		(*callback)(int, char *[]);
86*86d7f5d3SJohn Marino } databases[] = {
87*86d7f5d3SJohn Marino 	{	"ethers",	ethers,		},
88*86d7f5d3SJohn Marino 	{	"group",	group,		},
89*86d7f5d3SJohn Marino 	{	"hosts",	hosts,		},
90*86d7f5d3SJohn Marino 	{	"networks",	networks,	},
91*86d7f5d3SJohn Marino 	{	"passwd",	passwd,		},
92*86d7f5d3SJohn Marino 	{	"protocols",	protocols,	},
93*86d7f5d3SJohn Marino 	{	"rpc",		rpc,		},
94*86d7f5d3SJohn Marino 	{	"services",	services,	},
95*86d7f5d3SJohn Marino 	{	"shells",	shells,		},
96*86d7f5d3SJohn Marino 
97*86d7f5d3SJohn Marino 	{	NULL,		NULL,		},
98*86d7f5d3SJohn Marino };
99*86d7f5d3SJohn Marino 
100*86d7f5d3SJohn Marino int
main(int argc,char * argv[])101*86d7f5d3SJohn Marino main(int argc, char *argv[])
102*86d7f5d3SJohn Marino {
103*86d7f5d3SJohn Marino 	struct getentdb	*curdb;
104*86d7f5d3SJohn Marino 
105*86d7f5d3SJohn Marino 	setprogname(argv[0]);
106*86d7f5d3SJohn Marino 
107*86d7f5d3SJohn Marino 	if (argc < 2)
108*86d7f5d3SJohn Marino 		usage();
109*86d7f5d3SJohn Marino 	for (curdb = databases; curdb->name != NULL; curdb++) {
110*86d7f5d3SJohn Marino 		if (strcmp(curdb->name, argv[1]) == 0) {
111*86d7f5d3SJohn Marino 			exit(curdb->callback(argc, argv));
112*86d7f5d3SJohn Marino 		}
113*86d7f5d3SJohn Marino 	}
114*86d7f5d3SJohn Marino 	fprintf(stderr, "Unknown database: %s\n", argv[1]);
115*86d7f5d3SJohn Marino 	usage();
116*86d7f5d3SJohn Marino 	/* NOTREACHED */
117*86d7f5d3SJohn Marino 	return RV_USAGE;
118*86d7f5d3SJohn Marino }
119*86d7f5d3SJohn Marino 
120*86d7f5d3SJohn Marino static int
usage(void)121*86d7f5d3SJohn Marino usage(void)
122*86d7f5d3SJohn Marino {
123*86d7f5d3SJohn Marino 	struct getentdb	*curdb;
124*86d7f5d3SJohn Marino 
125*86d7f5d3SJohn Marino 	fprintf(stderr, "Usage: %s database [key ...]\n",
126*86d7f5d3SJohn Marino 	    getprogname());
127*86d7f5d3SJohn Marino 	fprintf(stderr, "       database may be one of:\n\t");
128*86d7f5d3SJohn Marino 	for (curdb = databases; curdb->name != NULL; curdb++) {
129*86d7f5d3SJohn Marino 		fprintf(stderr, " %s", curdb->name);
130*86d7f5d3SJohn Marino 	}
131*86d7f5d3SJohn Marino 	fprintf(stderr, "\n");
132*86d7f5d3SJohn Marino 	exit(RV_USAGE);
133*86d7f5d3SJohn Marino 	/* NOTREACHED */
134*86d7f5d3SJohn Marino }
135*86d7f5d3SJohn Marino 
136*86d7f5d3SJohn Marino static int
parsenum(const char * word,unsigned long * result)137*86d7f5d3SJohn Marino parsenum(const char *word, unsigned long *result)
138*86d7f5d3SJohn Marino {
139*86d7f5d3SJohn Marino 	unsigned long	num;
140*86d7f5d3SJohn Marino 	char		*ep;
141*86d7f5d3SJohn Marino 
142*86d7f5d3SJohn Marino 	assert(word != NULL);
143*86d7f5d3SJohn Marino 	assert(result != NULL);
144*86d7f5d3SJohn Marino 
145*86d7f5d3SJohn Marino 	if (!isdigit((unsigned char)word[0]))
146*86d7f5d3SJohn Marino 		return 0;
147*86d7f5d3SJohn Marino 	errno = 0;
148*86d7f5d3SJohn Marino 	num = strtoul(word, &ep, 10);
149*86d7f5d3SJohn Marino 	if (num == ULONG_MAX && errno == ERANGE)
150*86d7f5d3SJohn Marino 		return 0;
151*86d7f5d3SJohn Marino 	if (*ep != '\0')
152*86d7f5d3SJohn Marino 		return 0;
153*86d7f5d3SJohn Marino 	*result = num;
154*86d7f5d3SJohn Marino 	return 1;
155*86d7f5d3SJohn Marino }
156*86d7f5d3SJohn Marino 
157*86d7f5d3SJohn Marino /*
158*86d7f5d3SJohn Marino  * printfmtstrings --
159*86d7f5d3SJohn Marino  *	vprintf(format, ...),
160*86d7f5d3SJohn Marino  *	then the aliases (beginning with prefix, separated by sep),
161*86d7f5d3SJohn Marino  *	then a newline
162*86d7f5d3SJohn Marino  */
163*86d7f5d3SJohn Marino static void
printfmtstrings(char * strings[],const char * prefix,const char * sep,const char * fmt,...)164*86d7f5d3SJohn Marino printfmtstrings(char *strings[], const char *prefix, const char *sep,
165*86d7f5d3SJohn Marino 	const char *fmt, ...)
166*86d7f5d3SJohn Marino {
167*86d7f5d3SJohn Marino 	va_list		ap;
168*86d7f5d3SJohn Marino 	const char	*curpref;
169*86d7f5d3SJohn Marino 	int		i;
170*86d7f5d3SJohn Marino 
171*86d7f5d3SJohn Marino 	va_start(ap, fmt);
172*86d7f5d3SJohn Marino 	vprintf(fmt, ap);
173*86d7f5d3SJohn Marino 
174*86d7f5d3SJohn Marino 	curpref = prefix;
175*86d7f5d3SJohn Marino 	for (i = 0; strings[i] != NULL; i++) {
176*86d7f5d3SJohn Marino 		printf("%s%s", curpref, strings[i]);
177*86d7f5d3SJohn Marino 		curpref = sep;
178*86d7f5d3SJohn Marino 	}
179*86d7f5d3SJohn Marino 	printf("\n");
180*86d7f5d3SJohn Marino 	va_end(ap);
181*86d7f5d3SJohn Marino }
182*86d7f5d3SJohn Marino 
183*86d7f5d3SJohn Marino /*
184*86d7f5d3SJohn Marino  * ethers
185*86d7f5d3SJohn Marino  */
186*86d7f5d3SJohn Marino static int
ethers(int argc,char * argv[])187*86d7f5d3SJohn Marino ethers(int argc, char *argv[])
188*86d7f5d3SJohn Marino {
189*86d7f5d3SJohn Marino 	char		hostname[MAXHOSTNAMELEN + 1], *hp;
190*86d7f5d3SJohn Marino 	struct ether_addr ea, *eap;
191*86d7f5d3SJohn Marino 	int		i, rv;
192*86d7f5d3SJohn Marino 
193*86d7f5d3SJohn Marino 	assert(argc > 1);
194*86d7f5d3SJohn Marino 	assert(argv != NULL);
195*86d7f5d3SJohn Marino 
196*86d7f5d3SJohn Marino #define ETHERSPRINT	printf("%-17s  %s\n", ether_ntoa(eap), hp)
197*86d7f5d3SJohn Marino 
198*86d7f5d3SJohn Marino 	rv = RV_OK;
199*86d7f5d3SJohn Marino 	if (argc == 2) {
200*86d7f5d3SJohn Marino 		fprintf(stderr, "Enumeration not supported on ethers\n");
201*86d7f5d3SJohn Marino 		rv = RV_NOENUM;
202*86d7f5d3SJohn Marino 	} else {
203*86d7f5d3SJohn Marino 		for (i = 2; i < argc; i++) {
204*86d7f5d3SJohn Marino 			if ((eap = ether_aton(argv[i])) == NULL) {
205*86d7f5d3SJohn Marino 				eap = &ea;
206*86d7f5d3SJohn Marino 				hp = argv[i];
207*86d7f5d3SJohn Marino 				if (ether_hostton(hp, eap) != 0) {
208*86d7f5d3SJohn Marino 					rv = RV_NOTFOUND;
209*86d7f5d3SJohn Marino 					break;
210*86d7f5d3SJohn Marino 				}
211*86d7f5d3SJohn Marino 			} else {
212*86d7f5d3SJohn Marino 				hp = hostname;
213*86d7f5d3SJohn Marino 				if (ether_ntohost(hp, eap) != 0) {
214*86d7f5d3SJohn Marino 					rv = RV_NOTFOUND;
215*86d7f5d3SJohn Marino 					break;
216*86d7f5d3SJohn Marino 				}
217*86d7f5d3SJohn Marino 			}
218*86d7f5d3SJohn Marino 			ETHERSPRINT;
219*86d7f5d3SJohn Marino 		}
220*86d7f5d3SJohn Marino 	}
221*86d7f5d3SJohn Marino 	return rv;
222*86d7f5d3SJohn Marino }
223*86d7f5d3SJohn Marino 
224*86d7f5d3SJohn Marino /*
225*86d7f5d3SJohn Marino  * group
226*86d7f5d3SJohn Marino  */
227*86d7f5d3SJohn Marino 
228*86d7f5d3SJohn Marino static int
group(int argc,char * argv[])229*86d7f5d3SJohn Marino group(int argc, char *argv[])
230*86d7f5d3SJohn Marino {
231*86d7f5d3SJohn Marino 	struct group	*gr;
232*86d7f5d3SJohn Marino 	unsigned long	id;
233*86d7f5d3SJohn Marino 	int		i, rv;
234*86d7f5d3SJohn Marino 
235*86d7f5d3SJohn Marino 	assert(argc > 1);
236*86d7f5d3SJohn Marino 	assert(argv != NULL);
237*86d7f5d3SJohn Marino 
238*86d7f5d3SJohn Marino #define GROUPPRINT	printfmtstrings(gr->gr_mem, ":", ",", "%s:%s:%u", \
239*86d7f5d3SJohn Marino 			    gr->gr_name, gr->gr_passwd, gr->gr_gid)
240*86d7f5d3SJohn Marino 
241*86d7f5d3SJohn Marino 	setgroupent(1);
242*86d7f5d3SJohn Marino 	rv = RV_OK;
243*86d7f5d3SJohn Marino 	if (argc == 2) {
244*86d7f5d3SJohn Marino 		while ((gr = getgrent()) != NULL)
245*86d7f5d3SJohn Marino 			GROUPPRINT;
246*86d7f5d3SJohn Marino 	} else {
247*86d7f5d3SJohn Marino 		for (i = 2; i < argc; i++) {
248*86d7f5d3SJohn Marino 			if (parsenum(argv[i], &id))
249*86d7f5d3SJohn Marino 				gr = getgrgid((gid_t)id);
250*86d7f5d3SJohn Marino 			else
251*86d7f5d3SJohn Marino 				gr = getgrnam(argv[i]);
252*86d7f5d3SJohn Marino 			if (gr != NULL)
253*86d7f5d3SJohn Marino 				GROUPPRINT;
254*86d7f5d3SJohn Marino 			else {
255*86d7f5d3SJohn Marino 				rv = RV_NOTFOUND;
256*86d7f5d3SJohn Marino 				break;
257*86d7f5d3SJohn Marino 			}
258*86d7f5d3SJohn Marino 		}
259*86d7f5d3SJohn Marino 	}
260*86d7f5d3SJohn Marino 	endgrent();
261*86d7f5d3SJohn Marino 	return rv;
262*86d7f5d3SJohn Marino }
263*86d7f5d3SJohn Marino 
264*86d7f5d3SJohn Marino 
265*86d7f5d3SJohn Marino /*
266*86d7f5d3SJohn Marino  * hosts
267*86d7f5d3SJohn Marino  */
268*86d7f5d3SJohn Marino 
269*86d7f5d3SJohn Marino static void
hostsprint(const struct hostent * he)270*86d7f5d3SJohn Marino hostsprint(const struct hostent *he)
271*86d7f5d3SJohn Marino {
272*86d7f5d3SJohn Marino 	char	buf[INET6_ADDRSTRLEN];
273*86d7f5d3SJohn Marino 
274*86d7f5d3SJohn Marino 	assert(he != NULL);
275*86d7f5d3SJohn Marino 	if (inet_ntop(he->h_addrtype, he->h_addr, buf, sizeof(buf)) == NULL)
276*86d7f5d3SJohn Marino 		strlcpy(buf, "# unknown", sizeof(buf));
277*86d7f5d3SJohn Marino 	printfmtstrings(he->h_aliases, "  ", " ", "%-16s  %s", buf, he->h_name);
278*86d7f5d3SJohn Marino }
279*86d7f5d3SJohn Marino 
280*86d7f5d3SJohn Marino static int
hosts(int argc,char * argv[])281*86d7f5d3SJohn Marino hosts(int argc, char *argv[])
282*86d7f5d3SJohn Marino {
283*86d7f5d3SJohn Marino 	struct hostent	*he;
284*86d7f5d3SJohn Marino 	char		addr[IN6ADDRSZ];
285*86d7f5d3SJohn Marino 	int		i, rv;
286*86d7f5d3SJohn Marino 
287*86d7f5d3SJohn Marino 	assert(argc > 1);
288*86d7f5d3SJohn Marino 	assert(argv != NULL);
289*86d7f5d3SJohn Marino 
290*86d7f5d3SJohn Marino 	sethostent(1);
291*86d7f5d3SJohn Marino 	rv = RV_OK;
292*86d7f5d3SJohn Marino 	if (argc == 2) {
293*86d7f5d3SJohn Marino 		while ((he = gethostent()) != NULL)
294*86d7f5d3SJohn Marino 			hostsprint(he);
295*86d7f5d3SJohn Marino 	} else {
296*86d7f5d3SJohn Marino 		for (i = 2; i < argc; i++) {
297*86d7f5d3SJohn Marino 			if (inet_pton(AF_INET6, argv[i], (void *)addr) > 0)
298*86d7f5d3SJohn Marino 				he = gethostbyaddr(addr, IN6ADDRSZ, AF_INET6);
299*86d7f5d3SJohn Marino 			else if (inet_pton(AF_INET, argv[i], (void *)addr) > 0)
300*86d7f5d3SJohn Marino 				he = gethostbyaddr(addr, INADDRSZ, AF_INET);
301*86d7f5d3SJohn Marino 			else
302*86d7f5d3SJohn Marino 				he = gethostbyname(argv[i]);
303*86d7f5d3SJohn Marino 			if (he != NULL)
304*86d7f5d3SJohn Marino 				hostsprint(he);
305*86d7f5d3SJohn Marino 			else {
306*86d7f5d3SJohn Marino 				rv = RV_NOTFOUND;
307*86d7f5d3SJohn Marino 				break;
308*86d7f5d3SJohn Marino 			}
309*86d7f5d3SJohn Marino 		}
310*86d7f5d3SJohn Marino 	}
311*86d7f5d3SJohn Marino 	endhostent();
312*86d7f5d3SJohn Marino 	return rv;
313*86d7f5d3SJohn Marino }
314*86d7f5d3SJohn Marino 
315*86d7f5d3SJohn Marino /*
316*86d7f5d3SJohn Marino  * networks
317*86d7f5d3SJohn Marino  */
318*86d7f5d3SJohn Marino static void
networksprint(const struct netent * ne)319*86d7f5d3SJohn Marino networksprint(const struct netent *ne)
320*86d7f5d3SJohn Marino {
321*86d7f5d3SJohn Marino 	char		buf[INET6_ADDRSTRLEN];
322*86d7f5d3SJohn Marino 	struct	in_addr	ianet;
323*86d7f5d3SJohn Marino 
324*86d7f5d3SJohn Marino 	assert(ne != NULL);
325*86d7f5d3SJohn Marino 	ianet = inet_makeaddr(ne->n_net, 0);
326*86d7f5d3SJohn Marino 	if (inet_ntop(ne->n_addrtype, &ianet, buf, sizeof(buf)) == NULL)
327*86d7f5d3SJohn Marino 		strlcpy(buf, "# unknown", sizeof(buf));
328*86d7f5d3SJohn Marino 	printfmtstrings(ne->n_aliases, "  ", " ", "%-16s  %s", ne->n_name, buf);
329*86d7f5d3SJohn Marino }
330*86d7f5d3SJohn Marino 
331*86d7f5d3SJohn Marino static int
networks(int argc,char * argv[])332*86d7f5d3SJohn Marino networks(int argc, char *argv[])
333*86d7f5d3SJohn Marino {
334*86d7f5d3SJohn Marino 	struct netent	*ne;
335*86d7f5d3SJohn Marino 	in_addr_t	net;
336*86d7f5d3SJohn Marino 	int		i, rv;
337*86d7f5d3SJohn Marino 
338*86d7f5d3SJohn Marino 	assert(argc > 1);
339*86d7f5d3SJohn Marino 	assert(argv != NULL);
340*86d7f5d3SJohn Marino 
341*86d7f5d3SJohn Marino 	setnetent(1);
342*86d7f5d3SJohn Marino 	rv = RV_OK;
343*86d7f5d3SJohn Marino 	if (argc == 2) {
344*86d7f5d3SJohn Marino 		while ((ne = getnetent()) != NULL)
345*86d7f5d3SJohn Marino 			networksprint(ne);
346*86d7f5d3SJohn Marino 	} else {
347*86d7f5d3SJohn Marino 		for (i = 2; i < argc; i++) {
348*86d7f5d3SJohn Marino 			net = inet_network(argv[i]);
349*86d7f5d3SJohn Marino 			if (net != INADDR_NONE)
350*86d7f5d3SJohn Marino 				ne = getnetbyaddr(net, AF_INET);
351*86d7f5d3SJohn Marino 			else
352*86d7f5d3SJohn Marino 				ne = getnetbyname(argv[i]);
353*86d7f5d3SJohn Marino 			if (ne != NULL)
354*86d7f5d3SJohn Marino 				networksprint(ne);
355*86d7f5d3SJohn Marino 			else {
356*86d7f5d3SJohn Marino 				rv = RV_NOTFOUND;
357*86d7f5d3SJohn Marino 				break;
358*86d7f5d3SJohn Marino 			}
359*86d7f5d3SJohn Marino 		}
360*86d7f5d3SJohn Marino 	}
361*86d7f5d3SJohn Marino 	endnetent();
362*86d7f5d3SJohn Marino 	return rv;
363*86d7f5d3SJohn Marino }
364*86d7f5d3SJohn Marino 
365*86d7f5d3SJohn Marino /*
366*86d7f5d3SJohn Marino  * passwd
367*86d7f5d3SJohn Marino  */
368*86d7f5d3SJohn Marino static int
passwd(int argc,char * argv[])369*86d7f5d3SJohn Marino passwd(int argc, char *argv[])
370*86d7f5d3SJohn Marino {
371*86d7f5d3SJohn Marino 	struct passwd	*pw;
372*86d7f5d3SJohn Marino 	unsigned long	id;
373*86d7f5d3SJohn Marino 	int		i, rv;
374*86d7f5d3SJohn Marino 
375*86d7f5d3SJohn Marino 	assert(argc > 1);
376*86d7f5d3SJohn Marino 	assert(argv != NULL);
377*86d7f5d3SJohn Marino 
378*86d7f5d3SJohn Marino #define PASSWDPRINT	printf("%s:%s:%u:%u:%s:%s:%s\n", \
379*86d7f5d3SJohn Marino 			    pw->pw_name, pw->pw_passwd, pw->pw_uid, \
380*86d7f5d3SJohn Marino 			    pw->pw_gid, pw->pw_gecos, pw->pw_dir, pw->pw_shell)
381*86d7f5d3SJohn Marino 
382*86d7f5d3SJohn Marino 	setpassent(1);
383*86d7f5d3SJohn Marino 	rv = RV_OK;
384*86d7f5d3SJohn Marino 	if (argc == 2) {
385*86d7f5d3SJohn Marino 		while ((pw = getpwent()) != NULL)
386*86d7f5d3SJohn Marino 			PASSWDPRINT;
387*86d7f5d3SJohn Marino 	} else {
388*86d7f5d3SJohn Marino 		for (i = 2; i < argc; i++) {
389*86d7f5d3SJohn Marino 			if (parsenum(argv[i], &id))
390*86d7f5d3SJohn Marino 				pw = getpwuid((uid_t)id);
391*86d7f5d3SJohn Marino 			else
392*86d7f5d3SJohn Marino 				pw = getpwnam(argv[i]);
393*86d7f5d3SJohn Marino 			if (pw != NULL)
394*86d7f5d3SJohn Marino 				PASSWDPRINT;
395*86d7f5d3SJohn Marino 			else {
396*86d7f5d3SJohn Marino 				rv = RV_NOTFOUND;
397*86d7f5d3SJohn Marino 				break;
398*86d7f5d3SJohn Marino 			}
399*86d7f5d3SJohn Marino 		}
400*86d7f5d3SJohn Marino 	}
401*86d7f5d3SJohn Marino 	endpwent();
402*86d7f5d3SJohn Marino 	return rv;
403*86d7f5d3SJohn Marino }
404*86d7f5d3SJohn Marino 
405*86d7f5d3SJohn Marino /*
406*86d7f5d3SJohn Marino  * protocols
407*86d7f5d3SJohn Marino  */
408*86d7f5d3SJohn Marino static int
protocols(int argc,char * argv[])409*86d7f5d3SJohn Marino protocols(int argc, char *argv[])
410*86d7f5d3SJohn Marino {
411*86d7f5d3SJohn Marino 	struct protoent	*pe;
412*86d7f5d3SJohn Marino 	unsigned long	id;
413*86d7f5d3SJohn Marino 	int		i, rv;
414*86d7f5d3SJohn Marino 
415*86d7f5d3SJohn Marino 	assert(argc > 1);
416*86d7f5d3SJohn Marino 	assert(argv != NULL);
417*86d7f5d3SJohn Marino 
418*86d7f5d3SJohn Marino #define PROTOCOLSPRINT	printfmtstrings(pe->p_aliases, "  ", " ", \
419*86d7f5d3SJohn Marino 			    "%-16s  %5d", pe->p_name, pe->p_proto)
420*86d7f5d3SJohn Marino 
421*86d7f5d3SJohn Marino 	setprotoent(1);
422*86d7f5d3SJohn Marino 	rv = RV_OK;
423*86d7f5d3SJohn Marino 	if (argc == 2) {
424*86d7f5d3SJohn Marino 		while ((pe = getprotoent()) != NULL)
425*86d7f5d3SJohn Marino 			PROTOCOLSPRINT;
426*86d7f5d3SJohn Marino 	} else {
427*86d7f5d3SJohn Marino 		for (i = 2; i < argc; i++) {
428*86d7f5d3SJohn Marino 			if (parsenum(argv[i], &id))
429*86d7f5d3SJohn Marino 				pe = getprotobynumber((int)id);
430*86d7f5d3SJohn Marino 			else
431*86d7f5d3SJohn Marino 				pe = getprotobyname(argv[i]);
432*86d7f5d3SJohn Marino 			if (pe != NULL)
433*86d7f5d3SJohn Marino 				PROTOCOLSPRINT;
434*86d7f5d3SJohn Marino 			else {
435*86d7f5d3SJohn Marino 				rv = RV_NOTFOUND;
436*86d7f5d3SJohn Marino 				break;
437*86d7f5d3SJohn Marino 			}
438*86d7f5d3SJohn Marino 		}
439*86d7f5d3SJohn Marino 	}
440*86d7f5d3SJohn Marino 	endprotoent();
441*86d7f5d3SJohn Marino 	return rv;
442*86d7f5d3SJohn Marino }
443*86d7f5d3SJohn Marino 
444*86d7f5d3SJohn Marino /*
445*86d7f5d3SJohn Marino  * rpc
446*86d7f5d3SJohn Marino  */
447*86d7f5d3SJohn Marino static int
rpc(int argc,char * argv[])448*86d7f5d3SJohn Marino rpc(int argc, char *argv[])
449*86d7f5d3SJohn Marino {
450*86d7f5d3SJohn Marino 	struct rpcent	*re;
451*86d7f5d3SJohn Marino 	unsigned long	id;
452*86d7f5d3SJohn Marino 	int		i, rv;
453*86d7f5d3SJohn Marino 
454*86d7f5d3SJohn Marino 	assert(argc > 1);
455*86d7f5d3SJohn Marino 	assert(argv != NULL);
456*86d7f5d3SJohn Marino 
457*86d7f5d3SJohn Marino #define RPCPRINT	printfmtstrings(re->r_aliases, "  ", " ", \
458*86d7f5d3SJohn Marino 				"%-16s  %6d", \
459*86d7f5d3SJohn Marino 				re->r_name, re->r_number)
460*86d7f5d3SJohn Marino 
461*86d7f5d3SJohn Marino 	setrpcent(1);
462*86d7f5d3SJohn Marino 	rv = RV_OK;
463*86d7f5d3SJohn Marino 	if (argc == 2) {
464*86d7f5d3SJohn Marino 		while ((re = getrpcent()) != NULL)
465*86d7f5d3SJohn Marino 			RPCPRINT;
466*86d7f5d3SJohn Marino 	} else {
467*86d7f5d3SJohn Marino 		for (i = 2; i < argc; i++) {
468*86d7f5d3SJohn Marino 			if (parsenum(argv[i], &id))
469*86d7f5d3SJohn Marino 				re = getrpcbynumber((int)id);
470*86d7f5d3SJohn Marino 			else
471*86d7f5d3SJohn Marino 				re = getrpcbyname(argv[i]);
472*86d7f5d3SJohn Marino 			if (re != NULL)
473*86d7f5d3SJohn Marino 				RPCPRINT;
474*86d7f5d3SJohn Marino 			else {
475*86d7f5d3SJohn Marino 				rv = RV_NOTFOUND;
476*86d7f5d3SJohn Marino 				break;
477*86d7f5d3SJohn Marino 			}
478*86d7f5d3SJohn Marino 		}
479*86d7f5d3SJohn Marino 	}
480*86d7f5d3SJohn Marino 	endrpcent();
481*86d7f5d3SJohn Marino 	return rv;
482*86d7f5d3SJohn Marino }
483*86d7f5d3SJohn Marino 
484*86d7f5d3SJohn Marino /*
485*86d7f5d3SJohn Marino  * services
486*86d7f5d3SJohn Marino  */
487*86d7f5d3SJohn Marino static int
services(int argc,char * argv[])488*86d7f5d3SJohn Marino services(int argc, char *argv[])
489*86d7f5d3SJohn Marino {
490*86d7f5d3SJohn Marino 	struct servent	*se;
491*86d7f5d3SJohn Marino 	unsigned long	id;
492*86d7f5d3SJohn Marino 	char		*proto;
493*86d7f5d3SJohn Marino 	int		i, rv;
494*86d7f5d3SJohn Marino 
495*86d7f5d3SJohn Marino 	assert(argc > 1);
496*86d7f5d3SJohn Marino 	assert(argv != NULL);
497*86d7f5d3SJohn Marino 
498*86d7f5d3SJohn Marino #define SERVICESPRINT	printfmtstrings(se->s_aliases, "  ", " ", \
499*86d7f5d3SJohn Marino 			    "%-16s  %5d/%s", \
500*86d7f5d3SJohn Marino 			    se->s_name, ntohs(se->s_port), se->s_proto)
501*86d7f5d3SJohn Marino 
502*86d7f5d3SJohn Marino 	setservent(1);
503*86d7f5d3SJohn Marino 	rv = RV_OK;
504*86d7f5d3SJohn Marino 	if (argc == 2) {
505*86d7f5d3SJohn Marino 		while ((se = getservent()) != NULL)
506*86d7f5d3SJohn Marino 			SERVICESPRINT;
507*86d7f5d3SJohn Marino 	} else {
508*86d7f5d3SJohn Marino 		for (i = 2; i < argc; i++) {
509*86d7f5d3SJohn Marino 			proto = strchr(argv[i], '/');
510*86d7f5d3SJohn Marino 			if (proto != NULL)
511*86d7f5d3SJohn Marino 				*proto++ = '\0';
512*86d7f5d3SJohn Marino 			if (parsenum(argv[i], &id))
513*86d7f5d3SJohn Marino 				se = getservbyport(htons((u_short)id), proto);
514*86d7f5d3SJohn Marino 			else
515*86d7f5d3SJohn Marino 				se = getservbyname(argv[i], proto);
516*86d7f5d3SJohn Marino 			if (se != NULL)
517*86d7f5d3SJohn Marino 				SERVICESPRINT;
518*86d7f5d3SJohn Marino 			else {
519*86d7f5d3SJohn Marino 				rv = RV_NOTFOUND;
520*86d7f5d3SJohn Marino 				break;
521*86d7f5d3SJohn Marino 			}
522*86d7f5d3SJohn Marino 		}
523*86d7f5d3SJohn Marino 	}
524*86d7f5d3SJohn Marino 	endservent();
525*86d7f5d3SJohn Marino 	return rv;
526*86d7f5d3SJohn Marino }
527*86d7f5d3SJohn Marino 
528*86d7f5d3SJohn Marino /*
529*86d7f5d3SJohn Marino  * shells
530*86d7f5d3SJohn Marino  */
531*86d7f5d3SJohn Marino static int
shells(int argc,char * argv[])532*86d7f5d3SJohn Marino shells(int argc, char *argv[])
533*86d7f5d3SJohn Marino {
534*86d7f5d3SJohn Marino 	const char	*sh;
535*86d7f5d3SJohn Marino 	int		i, rv;
536*86d7f5d3SJohn Marino 
537*86d7f5d3SJohn Marino 	assert(argc > 1);
538*86d7f5d3SJohn Marino 	assert(argv != NULL);
539*86d7f5d3SJohn Marino 
540*86d7f5d3SJohn Marino #define SHELLSPRINT	printf("%s\n", sh)
541*86d7f5d3SJohn Marino 
542*86d7f5d3SJohn Marino 	setusershell();
543*86d7f5d3SJohn Marino 	rv = RV_OK;
544*86d7f5d3SJohn Marino 	if (argc == 2) {
545*86d7f5d3SJohn Marino 		while ((sh = getusershell()) != NULL)
546*86d7f5d3SJohn Marino 			SHELLSPRINT;
547*86d7f5d3SJohn Marino 	} else {
548*86d7f5d3SJohn Marino 		for (i = 2; i < argc; i++) {
549*86d7f5d3SJohn Marino 			setusershell();
550*86d7f5d3SJohn Marino 			while ((sh = getusershell()) != NULL) {
551*86d7f5d3SJohn Marino 				if (strcmp(sh, argv[i]) == 0) {
552*86d7f5d3SJohn Marino 					SHELLSPRINT;
553*86d7f5d3SJohn Marino 					break;
554*86d7f5d3SJohn Marino 				}
555*86d7f5d3SJohn Marino 			}
556*86d7f5d3SJohn Marino 			if (sh == NULL) {
557*86d7f5d3SJohn Marino 				rv = RV_NOTFOUND;
558*86d7f5d3SJohn Marino 				break;
559*86d7f5d3SJohn Marino 			}
560*86d7f5d3SJohn Marino 		}
561*86d7f5d3SJohn Marino 	}
562*86d7f5d3SJohn Marino 	endusershell();
563*86d7f5d3SJohn Marino 	return rv;
564*86d7f5d3SJohn Marino }
565