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