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 * Copyright (c) 2016 by Delphix. All rights reserved. 25 */ 26 27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * Portions of this source code were derived from Berkeley 32 * under license from the Regents of the University of 33 * California. 34 */ 35 36 #pragma ident "%Z%%M% %I% %E% SMI" 37 38 /* 39 * This is a user command which dumps each entry in a yp data base. It gets 40 * the stuff using the normal ypclnt package; the user doesn't get to choose 41 * which server gives them the input. Usage is: 42 * ypcat [-k] [-d domain] [-t] map 43 * ypcat -x 44 * where the -k switch will dump keys followed by a single blank space 45 * before the value, and the -d switch can be used to specify a domain other 46 * than the default domain. -t switch inhibits nickname translation of map 47 * names. -x is to dump the nickname translation table from file /var/yp/ 48 * nicknames. 49 * 50 */ 51 #ifdef NULL 52 #undef NULL 53 #endif 54 #define NULL 0 55 #include <stdio.h> 56 #include <rpc/rpc.h> 57 #include <rpcsvc/ypclnt.h> 58 #include <rpcsvc/yp_prot.h> 59 #include <string.h> 60 #include <unistd.h> 61 #include <stdlib.h> 62 63 static int translate = TRUE; 64 static int dodump = FALSE; 65 static int dumpkeys = FALSE; 66 static char *domain = NULL; 67 static char default_domain_name[YPMAXDOMAIN]; 68 static char nm[YPMAXMAP+1]; 69 static char *map = NULL; 70 static char nullstring[] = ""; 71 static char err_usage[] = 72 "Usage:\n\ 73 ypcat [-k] [-d domainname] [-t] mapname\n\ 74 ypcat -x\n\ 75 where\n\ 76 mapname may be either a mapname or a nickname for a map.\n\ 77 -t inhibits map nickname translation.\n\ 78 -k prints keys as well as values.\n\ 79 -x dumps the map nickname translation table.\n"; 80 static char err_bad_args[] = 81 "ypcat: %s argument is bad.\n"; 82 static char err_cant_get_kname[] = 83 "ypcat: can't get %s back from system call.\n"; 84 static char err_null_kname[] = 85 "ypcat: the %s hasn't been set on this machine.\n"; 86 static char err_bad_mapname[] = "mapname"; 87 static char err_bad_domainname[] = "domainname"; 88 static char err_first_failed[] = 89 "ypcat: can't get first record from yp. Reason: %s.\n"; 90 static char err_next_failed[] = 91 "ypcat: can't get next record from yp. Reason: %s.\n"; 92 93 static void get_command_line_args(); 94 static int callback(); 95 static void one_by_one_all(); 96 extern void maketable(); 97 extern int getmapname(); 98 static void getdomain(); 99 100 /* 101 * This is the mainline for the ypcat process. It pulls whatever arguments 102 * have been passed from the command line, and uses defaults for the rest. 103 */ 104 105 int 106 main(int argc, char ** argv) 107 { 108 int err; 109 int fail = 0; 110 struct ypall_callback cbinfo; 111 112 get_command_line_args(argc, argv); 113 114 if (dodump) { 115 maketable(dodump); 116 exit(0); 117 } 118 119 if (!domain) { 120 getdomain(); 121 } 122 123 if (translate && (strchr(map, '.') == NULL) && 124 (getmapname(map, nm))) { 125 map = nm; 126 } 127 128 cbinfo.foreach = callback; 129 cbinfo.data = (char *)&fail; 130 err = __yp_all_rsvdport(domain, map, &cbinfo); 131 132 if (err == YPERR_VERS) { 133 one_by_one_all(domain, map); 134 } else if (err) { 135 fail = TRUE; 136 fprintf(stderr, "%s\n", yperr_string(err)); 137 } 138 139 exit(fail); 140 } 141 142 /* 143 * This does the command line argument processing. 144 */ 145 static void 146 get_command_line_args(argc, argv) 147 int argc; 148 char **argv; 149 150 { 151 152 argv++; 153 154 while (--argc > 0 && (*argv)[0] == '-') { 155 156 switch ((*argv)[1]) { 157 158 case 't': 159 translate = FALSE; 160 break; 161 162 case 'k': 163 dumpkeys = TRUE; 164 break; 165 166 case 'x': 167 dodump = TRUE; 168 break; 169 170 case 'd': 171 172 if (argc > 1) { 173 argv++; 174 argc--; 175 domain = *argv; 176 177 if ((int)strlen(domain) > YPMAXDOMAIN) { 178 (void) fprintf(stderr, err_bad_args, 179 err_bad_domainname); 180 exit(1); 181 } 182 183 } else { 184 (void) fprintf(stderr, err_usage); 185 exit(1); 186 } 187 188 break; 189 190 default: 191 (void) fprintf(stderr, err_usage); 192 exit(1); 193 } 194 argv++; 195 } 196 197 if (!dodump) { 198 map = *argv; 199 if (argc < 1) { 200 (void) fprintf(stderr, err_usage); 201 exit(1); 202 } 203 if ((int)strlen(map) > YPMAXMAP) { 204 (void) fprintf(stderr, err_bad_args, err_bad_mapname); 205 exit(1); 206 } 207 } 208 } 209 210 /* 211 * This dumps out the value, optionally the key, and perhaps an error message. 212 */ 213 static int 214 callback(status, key, kl, val, vl, fail) 215 int status; 216 char *key; 217 int kl; 218 char *val; 219 int vl; 220 int *fail; 221 { 222 int e; 223 224 if (status == YP_TRUE) { 225 226 if (dumpkeys) 227 (void) printf("%.*s ", kl, key); 228 229 (void) printf("%.*s\n", vl, val); 230 return (FALSE); 231 } else { 232 233 e = ypprot_err(status); 234 235 if (e != YPERR_NOMORE) { 236 (void) fprintf(stderr, "%s\n", yperr_string(e)); 237 *fail = TRUE; 238 } 239 240 return (TRUE); 241 } 242 } 243 244 /* 245 * This cats the map out by using the old one-by-one enumeration interface. 246 * As such, it is prey to the old-style problems of rebinding to different 247 * servers during the enumeration. 248 */ 249 static void 250 one_by_one_all(domain, map) 251 char *domain; 252 char *map; 253 { 254 char *key; 255 int keylen; 256 char *outkey; 257 int outkeylen; 258 char *val; 259 int vallen; 260 int err; 261 262 key = nullstring; 263 keylen = 0; 264 val = nullstring; 265 vallen = 0; 266 267 if (err = yp_first(domain, map, &outkey, &outkeylen, &val, &vallen)) { 268 269 if (err == YPERR_NOMORE) { 270 exit(0); 271 } else { 272 (void) fprintf(stderr, err_first_failed, 273 yperr_string(err)); 274 exit(1); 275 } 276 } 277 278 for (;;) { 279 280 if (dumpkeys) { 281 (void) printf("%.*s ", outkeylen, outkey); 282 } 283 284 (void) printf("%.*s\n", vallen, val); 285 free(val); 286 key = outkey; 287 keylen = outkeylen; 288 289 if (err = yp_next(domain, map, key, keylen, &outkey, &outkeylen, 290 &val, &vallen)) { 291 292 if (err == YPERR_NOMORE) { 293 break; 294 } else { 295 (void) fprintf(stderr, err_next_failed, 296 yperr_string(err)); 297 exit(1); 298 } 299 } 300 301 free(key); 302 } 303 } 304 305 /* 306 * This gets the local default domainname, and makes sure that it's set 307 * to something reasonable. domain is set here. 308 */ 309 static void 310 getdomain() 311 { 312 if (!getdomainname(default_domain_name, YPMAXDOMAIN)) { 313 domain = default_domain_name; 314 } else { 315 (void) fprintf(stderr, err_cant_get_kname, err_bad_domainname); 316 exit(1); 317 } 318 319 if ((int)strlen(domain) == 0) { 320 (void) fprintf(stderr, err_null_kname, err_bad_domainname); 321 exit(1); 322 } 323 } 324