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