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