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