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 2005 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 /*
36 * This is a user command which looks up the value of a key in a map
37 *
38 * Usage is:
39 * ypmatch [-d domain] [-t] [-k] key [key ...] mname
40 * ypmatch -x
41 *
42 * where: the -d switch can be used to specify a domain other than the
43 * default domain. mname may be either a mapname, or a nickname which
44 * will be translated into a mapname according this translation. The
45 * -k switch prints keys as well as values. The -x switch may be used
46 * to dump the translation table.
47 */
48
49 #include <stdio.h>
50 #include <rpc/rpc.h>
51 #include <rpcsvc/yp_prot.h>
52 #include <rpcsvc/ypclnt.h>
53 #include <string.h>
54 #include <unistd.h>
55 #include <stdlib.h>
56
57 static void get_command_line_args();
58 static void getdomain();
59 static bool match_list();
60 static bool match_one();
61 static void print_one();
62 extern void maketable();
63 extern int getmapname();
64 extern int yp_match_rsvdport();
65
66 static int translate = TRUE;
67 static int dodump = FALSE;
68 static int printkeys = FALSE;
69 static char *domain = NULL;
70 static char default_domain_name[YPMAXDOMAIN];
71 static char *map = NULL;
72 static char nm[YPMAXMAP+1];
73 static char **keys = NULL;
74 static int nkeys;
75 static char err_usage[] =
76 "Usage:\n\
77 ypmatch [-d domain] [-t] [-k] key [key ...] mname\n\
78 ypmatch -x\n\
79 where\n\
80 mname may be either a mapname or a nickname for a map\n\
81 -t inhibits map nickname translation\n\
82 -k prints keys as well as values.\n\
83 -x dumps the map nickname translation table.\n";
84 static char err_bad_args[] =
85 "ypmatch: %s argument is bad.\n";
86 static char err_cant_get_kname[] =
87 "ypmatch: can't get %s back from system call.\n";
88 static char err_null_kname[] =
89 "ypmatch: the %s hasn't been set on this machine.\n";
90 static char err_bad_mapname[] = "mapname";
91 static char err_bad_domainname[] = "domainname";
92
93 /*
94 * This is the main line for the ypmatch process.
95 */
96 int
main(int argc,char ** argv)97 main(int argc, char **argv)
98 {
99 get_command_line_args(argc, argv);
100
101 if (dodump) {
102 maketable(dodump);
103 exit(0);
104 }
105
106 if (!domain) {
107 getdomain();
108 }
109
110 if (translate && (strchr(map, '.') == NULL) &&
111 (getmapname(map, nm))) {
112 map = nm;
113 }
114
115 if (!match_list())
116 return (1);
117 return (0);
118 }
119
120 /*
121 * This does the command line argument processing.
122 */
123 static void
get_command_line_args(argc,argv)124 get_command_line_args(argc, argv)
125 int argc;
126 char **argv;
127
128 {
129
130 if (argc < 2) {
131 (void) fprintf(stderr, err_usage);
132 exit(1);
133 }
134 argv++;
135
136 while (--argc > 0 && (*argv)[0] == '-') {
137
138 switch ((*argv)[1]) {
139
140 case 't':
141 translate = FALSE;
142 break;
143
144 case 'k':
145 printkeys = TRUE;
146 break;
147
148 case 'x':
149 dodump = TRUE;
150 break;
151
152 case 'd':
153
154 if (argc > 1) {
155 argv++;
156 argc--;
157 domain = *argv;
158
159 if ((int)strlen(domain) > YPMAXDOMAIN) {
160 (void) fprintf(stderr, err_bad_args,
161 err_bad_domainname);
162 exit(1);
163 }
164
165 } else {
166 (void) fprintf(stderr, err_usage);
167 exit(1);
168 }
169
170 break;
171
172 default:
173 (void) fprintf(stderr, err_usage);
174 exit(1);
175 }
176
177 argv++;
178 }
179
180 if (!dodump) {
181 if (argc < 2) {
182 (void) fprintf(stderr, err_usage);
183 exit(1);
184 }
185
186 keys = argv;
187 nkeys = argc -1;
188 map = argv[argc -1];
189
190 if ((int)strlen(map) > YPMAXMAP) {
191 (void) fprintf(stderr, err_bad_args, err_bad_mapname);
192 exit(1);
193 }
194 }
195 }
196
197 /*
198 * This gets the local default domainname, and makes sure that it's set
199 * to something reasonable. domain is set here.
200 */
201 static void
getdomain()202 getdomain()
203 {
204 if (!getdomainname(default_domain_name, YPMAXDOMAIN)) {
205 domain = default_domain_name;
206 } else {
207 (void) fprintf(stderr, err_cant_get_kname, err_bad_domainname);
208 exit(1);
209 }
210
211 if ((int)strlen(domain) == 0) {
212 (void) fprintf(stderr, err_null_kname, err_bad_domainname);
213 exit(1);
214 }
215 }
216
217 /*
218 * This traverses the list of argument keys.
219 */
220 static bool
match_list()221 match_list()
222 {
223 bool error;
224 bool errors = FALSE;
225 char *val;
226 int len;
227 int n = 0;
228
229 while (n < nkeys) {
230 error = match_one(keys[n], &val, &len);
231
232 if (!error) {
233 print_one(keys[n], val, len);
234 free(val);
235 } else {
236 errors = TRUE;
237 }
238
239 n++;
240 }
241
242 return (!errors);
243 }
244
245 /*
246 * This fires off a "match" request to any old yp server, using the vanilla
247 * yp client interface. To cover the case in which trailing NULLs are included
248 * in the keys, this retrys the match request including the NULL if the key
249 * isn't in the map.
250 */
251 static bool
match_one(key,val,len)252 match_one(key, val, len)
253 char *key;
254 char **val;
255 int *len;
256 {
257 int err;
258 bool error = FALSE;
259
260 *val = NULL;
261 *len = 0;
262 err = yp_match_rsvdport(domain, map, key, (int)strlen(key), val, len);
263
264
265 if (err == YPERR_KEY) {
266 err = yp_match_rsvdport(domain, map, key,
267 ((int)strlen(key) + 1),
268 val, len);
269 }
270
271 if (err) {
272 (void) fprintf(stderr,
273 "Can't match key %s in map %s. Reason: %s.\n", key, map,
274 yperr_string(err));
275 error = TRUE;
276 }
277
278 return (error);
279 }
280
281 /*
282 * This prints the value, (and optionally, the key) after first checking that
283 * the last char in the value isn't a NULL. If the last char is a NULL, the
284 * \n\0 sequence which the yp client layer has given to us is shuffled back
285 * one byte.
286 */
287 static void
print_one(key,val,len)288 print_one(key, val, len)
289 char *key;
290 char *val;
291 int len;
292 {
293 if (printkeys) {
294 (void) printf("%s: ", key);
295 }
296
297 (void) printf("%.*s\n", len, val);
298 }
299