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