xref: /onnv-gate/usr/src/cmd/ypcmd/ypmatch.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  *
22*0Sstevel@tonic-gate  * Copyright 1995 Sun Microsystems, Inc.  All rights reserved.
23*0Sstevel@tonic-gate  * Use is subject to license terms.
24*0Sstevel@tonic-gate  */
25*0Sstevel@tonic-gate 
26*0Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27*0Sstevel@tonic-gate /*	  All Rights Reserved   */
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley
31*0Sstevel@tonic-gate  * under license from the Regents of the University of
32*0Sstevel@tonic-gate  * California.
33*0Sstevel@tonic-gate  */
34*0Sstevel@tonic-gate 
35*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
36*0Sstevel@tonic-gate 
37*0Sstevel@tonic-gate /*
38*0Sstevel@tonic-gate  * This is a user command which looks up the value of a key in a map
39*0Sstevel@tonic-gate  *
40*0Sstevel@tonic-gate  * Usage is:
41*0Sstevel@tonic-gate  *	ypmatch [-d domain] [-t] [-k] key [key ...] mname
42*0Sstevel@tonic-gate  *  ypmatch -x
43*0Sstevel@tonic-gate  *
44*0Sstevel@tonic-gate  * where:  the -d switch can be used to specify a domain other than the
45*0Sstevel@tonic-gate  * default domain.  mname may be either a mapname, or a nickname which
46*0Sstevel@tonic-gate  * will be translated into a mapname according this translation.  The
47*0Sstevel@tonic-gate  * -k switch prints keys as well as values. The -x switch may be used
48*0Sstevel@tonic-gate  * to dump the translation table.
49*0Sstevel@tonic-gate  */
50*0Sstevel@tonic-gate 
51*0Sstevel@tonic-gate #include <stdio.h>
52*0Sstevel@tonic-gate #include <rpc/rpc.h>
53*0Sstevel@tonic-gate #include <rpcsvc/yp_prot.h>
54*0Sstevel@tonic-gate #include <rpcsvc/ypclnt.h>
55*0Sstevel@tonic-gate #include <string.h>
56*0Sstevel@tonic-gate #include <unistd.h>
57*0Sstevel@tonic-gate #include <stdlib.h>
58*0Sstevel@tonic-gate 
59*0Sstevel@tonic-gate static void get_command_line_args();
60*0Sstevel@tonic-gate static void getdomain();
61*0Sstevel@tonic-gate static bool match_list();
62*0Sstevel@tonic-gate static bool match_one();
63*0Sstevel@tonic-gate static void print_one();
64*0Sstevel@tonic-gate extern void maketable();
65*0Sstevel@tonic-gate extern int getmapname();
66*0Sstevel@tonic-gate extern int yp_match_rsvdport ();
67*0Sstevel@tonic-gate 
68*0Sstevel@tonic-gate static int translate = TRUE;
69*0Sstevel@tonic-gate static int dodump = FALSE;
70*0Sstevel@tonic-gate static int printkeys = FALSE;
71*0Sstevel@tonic-gate static char *domain = NULL;
72*0Sstevel@tonic-gate static char default_domain_name[YPMAXDOMAIN];
73*0Sstevel@tonic-gate static char *map = NULL;
74*0Sstevel@tonic-gate static char nm[YPMAXMAP+1];
75*0Sstevel@tonic-gate static char **keys = NULL;
76*0Sstevel@tonic-gate static int nkeys;
77*0Sstevel@tonic-gate static char err_usage[] =
78*0Sstevel@tonic-gate "Usage:\n\
79*0Sstevel@tonic-gate 	ypmatch [-d domain] [-t] [-k] key [key ...] mname\n\
80*0Sstevel@tonic-gate 	ypmatch -x\n\
81*0Sstevel@tonic-gate where\n\
82*0Sstevel@tonic-gate 	mname may be either a mapname or a nickname for a map\n\
83*0Sstevel@tonic-gate 	-t inhibits map nickname translation\n\
84*0Sstevel@tonic-gate 	-k prints keys as well as values.\n\
85*0Sstevel@tonic-gate 	-x dumps the map nickname translation table.\n";
86*0Sstevel@tonic-gate static char err_bad_args[] =
87*0Sstevel@tonic-gate 	"ypmatch:  %s argument is bad.\n";
88*0Sstevel@tonic-gate static char err_cant_get_kname[] =
89*0Sstevel@tonic-gate 	"ypmatch:  can't get %s back from system call.\n";
90*0Sstevel@tonic-gate static char err_null_kname[] =
91*0Sstevel@tonic-gate 	"ypmatch:  the %s hasn't been set on this machine.\n";
92*0Sstevel@tonic-gate static char err_bad_mapname[] = "mapname";
93*0Sstevel@tonic-gate static char err_bad_domainname[] = "domainname";
94*0Sstevel@tonic-gate 
95*0Sstevel@tonic-gate /*
96*0Sstevel@tonic-gate  * This is the main line for the ypmatch process.
97*0Sstevel@tonic-gate  */
98*0Sstevel@tonic-gate main(argc, argv)
99*0Sstevel@tonic-gate 	char **argv;
100*0Sstevel@tonic-gate {
101*0Sstevel@tonic-gate 	get_command_line_args(argc, argv);
102*0Sstevel@tonic-gate 
103*0Sstevel@tonic-gate 	if (dodump) {
104*0Sstevel@tonic-gate 		maketable(dodump);
105*0Sstevel@tonic-gate 		exit(0);
106*0Sstevel@tonic-gate 	}
107*0Sstevel@tonic-gate 
108*0Sstevel@tonic-gate 	if (!domain) {
109*0Sstevel@tonic-gate 		getdomain();
110*0Sstevel@tonic-gate 	}
111*0Sstevel@tonic-gate 
112*0Sstevel@tonic-gate 	if (translate && (strchr(map, '.') == NULL) &&
113*0Sstevel@tonic-gate 		(getmapname(map, nm))) {
114*0Sstevel@tonic-gate 		map = nm;
115*0Sstevel@tonic-gate 	}
116*0Sstevel@tonic-gate 
117*0Sstevel@tonic-gate 	if (!match_list())
118*0Sstevel@tonic-gate 		return (1);
119*0Sstevel@tonic-gate 	return (0);
120*0Sstevel@tonic-gate }
121*0Sstevel@tonic-gate 
122*0Sstevel@tonic-gate /*
123*0Sstevel@tonic-gate  * This does the command line argument processing.
124*0Sstevel@tonic-gate  */
125*0Sstevel@tonic-gate static void
126*0Sstevel@tonic-gate get_command_line_args(argc, argv)
127*0Sstevel@tonic-gate 	int argc;
128*0Sstevel@tonic-gate 	char **argv;
129*0Sstevel@tonic-gate 
130*0Sstevel@tonic-gate {
131*0Sstevel@tonic-gate 
132*0Sstevel@tonic-gate 	if (argc < 2) {
133*0Sstevel@tonic-gate 		(void) fprintf(stderr, err_usage);
134*0Sstevel@tonic-gate 		exit(1);
135*0Sstevel@tonic-gate 	}
136*0Sstevel@tonic-gate 	argv++;
137*0Sstevel@tonic-gate 
138*0Sstevel@tonic-gate 	while (--argc > 0 && (*argv)[0] == '-') {
139*0Sstevel@tonic-gate 
140*0Sstevel@tonic-gate 		switch ((*argv)[1]) {
141*0Sstevel@tonic-gate 
142*0Sstevel@tonic-gate 		case 't':
143*0Sstevel@tonic-gate 			translate = FALSE;
144*0Sstevel@tonic-gate 			break;
145*0Sstevel@tonic-gate 
146*0Sstevel@tonic-gate 		case 'k':
147*0Sstevel@tonic-gate 			printkeys = TRUE;
148*0Sstevel@tonic-gate 			break;
149*0Sstevel@tonic-gate 
150*0Sstevel@tonic-gate 		case 'x':
151*0Sstevel@tonic-gate 			dodump = TRUE;
152*0Sstevel@tonic-gate 			break;
153*0Sstevel@tonic-gate 
154*0Sstevel@tonic-gate 		case 'd':
155*0Sstevel@tonic-gate 
156*0Sstevel@tonic-gate 			if (argc > 1) {
157*0Sstevel@tonic-gate 				argv++;
158*0Sstevel@tonic-gate 				argc--;
159*0Sstevel@tonic-gate 				domain = *argv;
160*0Sstevel@tonic-gate 
161*0Sstevel@tonic-gate 				if ((int) strlen(domain) > YPMAXDOMAIN) {
162*0Sstevel@tonic-gate 					(void) fprintf(stderr, err_bad_args,
163*0Sstevel@tonic-gate 					    err_bad_domainname);
164*0Sstevel@tonic-gate 					exit(1);
165*0Sstevel@tonic-gate 				}
166*0Sstevel@tonic-gate 
167*0Sstevel@tonic-gate 			} else {
168*0Sstevel@tonic-gate 				(void) fprintf(stderr, err_usage);
169*0Sstevel@tonic-gate 				exit(1);
170*0Sstevel@tonic-gate 			}
171*0Sstevel@tonic-gate 
172*0Sstevel@tonic-gate 			break;
173*0Sstevel@tonic-gate 
174*0Sstevel@tonic-gate 		default:
175*0Sstevel@tonic-gate 			(void) fprintf(stderr, err_usage);
176*0Sstevel@tonic-gate 			exit(1);
177*0Sstevel@tonic-gate 		}
178*0Sstevel@tonic-gate 
179*0Sstevel@tonic-gate 		argv++;
180*0Sstevel@tonic-gate 	}
181*0Sstevel@tonic-gate 
182*0Sstevel@tonic-gate 	if (!dodump) {
183*0Sstevel@tonic-gate 		if (argc < 2) {
184*0Sstevel@tonic-gate 			(void) fprintf(stderr, err_usage);
185*0Sstevel@tonic-gate 			exit(1);
186*0Sstevel@tonic-gate 		}
187*0Sstevel@tonic-gate 
188*0Sstevel@tonic-gate 		keys = argv;
189*0Sstevel@tonic-gate 		nkeys = argc -1;
190*0Sstevel@tonic-gate 		map = argv[argc -1];
191*0Sstevel@tonic-gate 
192*0Sstevel@tonic-gate 		if ((int) strlen(map) > YPMAXMAP) {
193*0Sstevel@tonic-gate 			(void) fprintf(stderr, err_bad_args, err_bad_mapname);
194*0Sstevel@tonic-gate 			exit(1);
195*0Sstevel@tonic-gate 		}
196*0Sstevel@tonic-gate 	}
197*0Sstevel@tonic-gate }
198*0Sstevel@tonic-gate 
199*0Sstevel@tonic-gate /*
200*0Sstevel@tonic-gate  * This gets the local default domainname, and makes sure that it's set
201*0Sstevel@tonic-gate  * to something reasonable.  domain is set here.
202*0Sstevel@tonic-gate  */
203*0Sstevel@tonic-gate static void
204*0Sstevel@tonic-gate getdomain()
205*0Sstevel@tonic-gate {
206*0Sstevel@tonic-gate 	if (!getdomainname(default_domain_name, YPMAXDOMAIN)) {
207*0Sstevel@tonic-gate 		domain = default_domain_name;
208*0Sstevel@tonic-gate 	} else {
209*0Sstevel@tonic-gate 		(void) fprintf(stderr, err_cant_get_kname, err_bad_domainname);
210*0Sstevel@tonic-gate 		exit(1);
211*0Sstevel@tonic-gate 	}
212*0Sstevel@tonic-gate 
213*0Sstevel@tonic-gate 	if ((int) strlen(domain) == 0) {
214*0Sstevel@tonic-gate 		(void) fprintf(stderr, err_null_kname, err_bad_domainname);
215*0Sstevel@tonic-gate 		exit(1);
216*0Sstevel@tonic-gate 	}
217*0Sstevel@tonic-gate }
218*0Sstevel@tonic-gate 
219*0Sstevel@tonic-gate /*
220*0Sstevel@tonic-gate  * This traverses the list of argument keys.
221*0Sstevel@tonic-gate  */
222*0Sstevel@tonic-gate static bool
223*0Sstevel@tonic-gate match_list()
224*0Sstevel@tonic-gate {
225*0Sstevel@tonic-gate 	bool error;
226*0Sstevel@tonic-gate 	bool errors = FALSE;
227*0Sstevel@tonic-gate 	char *val;
228*0Sstevel@tonic-gate 	int len;
229*0Sstevel@tonic-gate 	int n = 0;
230*0Sstevel@tonic-gate 
231*0Sstevel@tonic-gate 	while (n < nkeys) {
232*0Sstevel@tonic-gate 		error = match_one(keys[n], &val, &len);
233*0Sstevel@tonic-gate 
234*0Sstevel@tonic-gate 		if (!error) {
235*0Sstevel@tonic-gate 			print_one(keys[n], val, len);
236*0Sstevel@tonic-gate 			free(val);
237*0Sstevel@tonic-gate 		} else {
238*0Sstevel@tonic-gate 			errors = TRUE;
239*0Sstevel@tonic-gate 		}
240*0Sstevel@tonic-gate 
241*0Sstevel@tonic-gate 		n++;
242*0Sstevel@tonic-gate 	}
243*0Sstevel@tonic-gate 
244*0Sstevel@tonic-gate 	return (!errors);
245*0Sstevel@tonic-gate }
246*0Sstevel@tonic-gate 
247*0Sstevel@tonic-gate /*
248*0Sstevel@tonic-gate  * This fires off a "match" request to any old yp server, using the vanilla
249*0Sstevel@tonic-gate  * yp client interface.  To cover the case in which trailing NULLs are included
250*0Sstevel@tonic-gate  * in the keys, this retrys the match request including the NULL if the key
251*0Sstevel@tonic-gate  * isn't in the map.
252*0Sstevel@tonic-gate  */
253*0Sstevel@tonic-gate static bool
254*0Sstevel@tonic-gate match_one(key, val, len)
255*0Sstevel@tonic-gate 	char *key;
256*0Sstevel@tonic-gate 	char **val;
257*0Sstevel@tonic-gate 	int *len;
258*0Sstevel@tonic-gate {
259*0Sstevel@tonic-gate 	int err;
260*0Sstevel@tonic-gate 	bool error = FALSE;
261*0Sstevel@tonic-gate 
262*0Sstevel@tonic-gate 	*val = NULL;
263*0Sstevel@tonic-gate 	*len = 0;
264*0Sstevel@tonic-gate 	err = yp_match_rsvdport(domain, map, key, (int) strlen(key), val, len);
265*0Sstevel@tonic-gate 
266*0Sstevel@tonic-gate 
267*0Sstevel@tonic-gate 	if (err == YPERR_KEY) {
268*0Sstevel@tonic-gate 		err = yp_match_rsvdport(domain, map, key, ((int) strlen(key) + 1),
269*0Sstevel@tonic-gate 		    val, len);
270*0Sstevel@tonic-gate 	}
271*0Sstevel@tonic-gate 
272*0Sstevel@tonic-gate 	if (err) {
273*0Sstevel@tonic-gate 		(void) fprintf(stderr,
274*0Sstevel@tonic-gate 		    "Can't match key %s in map %s.  Reason: %s.\n", key, map,
275*0Sstevel@tonic-gate 		    yperr_string(err));
276*0Sstevel@tonic-gate 		error = TRUE;
277*0Sstevel@tonic-gate 	}
278*0Sstevel@tonic-gate 
279*0Sstevel@tonic-gate 	return (error);
280*0Sstevel@tonic-gate }
281*0Sstevel@tonic-gate 
282*0Sstevel@tonic-gate /*
283*0Sstevel@tonic-gate  * This prints the value, (and optionally, the key) after first checking that
284*0Sstevel@tonic-gate  * the last char in the value isn't a NULL.  If the last char is a NULL, the
285*0Sstevel@tonic-gate  * \n\0 sequence which the yp client layer has given to us is shuffled back
286*0Sstevel@tonic-gate  * one byte.
287*0Sstevel@tonic-gate  */
288*0Sstevel@tonic-gate static void
289*0Sstevel@tonic-gate print_one(key, val, len)
290*0Sstevel@tonic-gate 	char *key;
291*0Sstevel@tonic-gate 	char *val;
292*0Sstevel@tonic-gate 	int len;
293*0Sstevel@tonic-gate {
294*0Sstevel@tonic-gate 	if (printkeys) {
295*0Sstevel@tonic-gate 		(void) printf("%s: ", key);
296*0Sstevel@tonic-gate 	}
297*0Sstevel@tonic-gate 
298*0Sstevel@tonic-gate 	(void) printf("%.*s\n", len, val);
299*0Sstevel@tonic-gate }
300