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