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 #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 int 99 main(argc, argv) 100 char **argv; 101 { 102 get_command_line_args(argc, argv); 103 104 if (dodump) { 105 maketable(dodump); 106 exit(0); 107 } 108 109 if (!domain) { 110 getdomain(); 111 } 112 113 if (translate && (strchr(map, '.') == NULL) && 114 (getmapname(map, nm))) { 115 map = nm; 116 } 117 118 if (!match_list()) 119 return (1); 120 return (0); 121 } 122 123 /* 124 * This does the command line argument processing. 125 */ 126 static void 127 get_command_line_args(argc, argv) 128 int argc; 129 char **argv; 130 131 { 132 133 if (argc < 2) { 134 (void) fprintf(stderr, err_usage); 135 exit(1); 136 } 137 argv++; 138 139 while (--argc > 0 && (*argv)[0] == '-') { 140 141 switch ((*argv)[1]) { 142 143 case 't': 144 translate = FALSE; 145 break; 146 147 case 'k': 148 printkeys = TRUE; 149 break; 150 151 case 'x': 152 dodump = TRUE; 153 break; 154 155 case 'd': 156 157 if (argc > 1) { 158 argv++; 159 argc--; 160 domain = *argv; 161 162 if ((int)strlen(domain) > YPMAXDOMAIN) { 163 (void) fprintf(stderr, err_bad_args, 164 err_bad_domainname); 165 exit(1); 166 } 167 168 } else { 169 (void) fprintf(stderr, err_usage); 170 exit(1); 171 } 172 173 break; 174 175 default: 176 (void) fprintf(stderr, err_usage); 177 exit(1); 178 } 179 180 argv++; 181 } 182 183 if (!dodump) { 184 if (argc < 2) { 185 (void) fprintf(stderr, err_usage); 186 exit(1); 187 } 188 189 keys = argv; 190 nkeys = argc -1; 191 map = argv[argc -1]; 192 193 if ((int)strlen(map) > YPMAXMAP) { 194 (void) fprintf(stderr, err_bad_args, err_bad_mapname); 195 exit(1); 196 } 197 } 198 } 199 200 /* 201 * This gets the local default domainname, and makes sure that it's set 202 * to something reasonable. domain is set here. 203 */ 204 static void 205 getdomain() 206 { 207 if (!getdomainname(default_domain_name, YPMAXDOMAIN)) { 208 domain = default_domain_name; 209 } else { 210 (void) fprintf(stderr, err_cant_get_kname, err_bad_domainname); 211 exit(1); 212 } 213 214 if ((int)strlen(domain) == 0) { 215 (void) fprintf(stderr, err_null_kname, err_bad_domainname); 216 exit(1); 217 } 218 } 219 220 /* 221 * This traverses the list of argument keys. 222 */ 223 static bool 224 match_list() 225 { 226 bool error; 227 bool errors = FALSE; 228 char *val; 229 int len; 230 int n = 0; 231 232 while (n < nkeys) { 233 error = match_one(keys[n], &val, &len); 234 235 if (!error) { 236 print_one(keys[n], val, len); 237 free(val); 238 } else { 239 errors = TRUE; 240 } 241 242 n++; 243 } 244 245 return (!errors); 246 } 247 248 /* 249 * This fires off a "match" request to any old yp server, using the vanilla 250 * yp client interface. To cover the case in which trailing NULLs are included 251 * in the keys, this retrys the match request including the NULL if the key 252 * isn't in the map. 253 */ 254 static bool 255 match_one(key, val, len) 256 char *key; 257 char **val; 258 int *len; 259 { 260 int err; 261 bool error = FALSE; 262 263 *val = NULL; 264 *len = 0; 265 err = yp_match_rsvdport(domain, map, key, (int)strlen(key), val, len); 266 267 268 if (err == YPERR_KEY) { 269 err = yp_match_rsvdport(domain, map, key, 270 ((int)strlen(key) + 1), 271 val, len); 272 } 273 274 if (err) { 275 (void) fprintf(stderr, 276 "Can't match key %s in map %s. Reason: %s.\n", key, map, 277 yperr_string(err)); 278 error = TRUE; 279 } 280 281 return (error); 282 } 283 284 /* 285 * This prints the value, (and optionally, the key) after first checking that 286 * the last char in the value isn't a NULL. If the last char is a NULL, the 287 * \n\0 sequence which the yp client layer has given to us is shuffled back 288 * one byte. 289 */ 290 static void 291 print_one(key, val, len) 292 char *key; 293 char *val; 294 int len; 295 { 296 if (printkeys) { 297 (void) printf("%s: ", key); 298 } 299 300 (void) printf("%.*s\n", len, val); 301 } 302