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 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 int 105 main(int argc, char ** argv) 106 { 107 int err; 108 int fail = 0; 109 struct ypall_callback cbinfo; 110 111 get_command_line_args(argc, argv); 112 113 if (dodump) { 114 maketable(dodump); 115 exit(0); 116 } 117 118 if (!domain) { 119 getdomain(); 120 } 121 122 if (translate && (strchr(map, '.') == NULL) && 123 (getmapname(map, nm))) { 124 map = nm; 125 } 126 127 cbinfo.foreach = callback; 128 cbinfo.data = (char *)&fail; 129 err = __yp_all_rsvdport(domain, map, &cbinfo); 130 131 if (err == YPERR_VERS) { 132 one_by_one_all(domain, map); 133 } else if (err) { 134 fail = TRUE; 135 fprintf(stderr, "%s\n", yperr_string(err)); 136 } 137 138 exit(fail); 139 } 140 141 /* 142 * This does the command line argument processing. 143 */ 144 static void 145 get_command_line_args(argc, argv) 146 int argc; 147 char **argv; 148 149 { 150 151 argv++; 152 153 while (--argc > 0 && (*argv)[0] == '-') { 154 155 switch ((*argv)[1]) { 156 157 case 't': 158 translate = FALSE; 159 break; 160 161 case 'k': 162 dumpkeys = TRUE; 163 break; 164 165 case 'x': 166 dodump = TRUE; 167 break; 168 169 case 'd': 170 171 if (argc > 1) { 172 argv++; 173 argc--; 174 domain = *argv; 175 176 if ((int)strlen(domain) > YPMAXDOMAIN) { 177 (void) fprintf(stderr, err_bad_args, 178 err_bad_domainname); 179 exit(1); 180 } 181 182 } else { 183 (void) fprintf(stderr, err_usage); 184 exit(1); 185 } 186 187 break; 188 189 default: 190 (void) fprintf(stderr, err_usage); 191 exit(1); 192 } 193 argv++; 194 } 195 196 if (!dodump) { 197 map = *argv; 198 if (argc < 1) { 199 (void) fprintf(stderr, err_usage); 200 exit(1); 201 } 202 if ((int)strlen(map) > YPMAXMAP) { 203 (void) fprintf(stderr, err_bad_args, err_bad_mapname); 204 exit(1); 205 } 206 } 207 } 208 209 /* 210 * This dumps out the value, optionally the key, and perhaps an error message. 211 */ 212 static int 213 callback(status, key, kl, val, vl, fail) 214 int status; 215 char *key; 216 int kl; 217 char *val; 218 int vl; 219 int *fail; 220 { 221 int e; 222 223 if (status == YP_TRUE) { 224 225 if (dumpkeys) 226 (void) printf("%.*s ", kl, key); 227 228 (void) printf("%.*s\n", vl, val); 229 return (FALSE); 230 } else { 231 232 e = ypprot_err(status); 233 234 if (e != YPERR_NOMORE) { 235 (void) fprintf(stderr, "%s\n", yperr_string(e)); 236 *fail = TRUE; 237 } 238 239 return (TRUE); 240 } 241 } 242 243 /* 244 * This cats the map out by using the old one-by-one enumeration interface. 245 * As such, it is prey to the old-style problems of rebinding to different 246 * servers during the enumeration. 247 */ 248 static void 249 one_by_one_all(domain, map) 250 char *domain; 251 char *map; 252 { 253 char *key; 254 int keylen; 255 char *outkey; 256 int outkeylen; 257 char *val; 258 int vallen; 259 int err; 260 261 key = nullstring; 262 keylen = 0; 263 val = nullstring; 264 vallen = 0; 265 266 if (err = yp_first(domain, map, &outkey, &outkeylen, &val, &vallen)) { 267 268 if (err == YPERR_NOMORE) { 269 exit(0); 270 } else { 271 (void) fprintf(stderr, err_first_failed, 272 yperr_string(err)); 273 exit(1); 274 } 275 } 276 277 for (;;) { 278 279 if (dumpkeys) { 280 (void) printf("%.*s ", outkeylen, outkey); 281 } 282 283 (void) printf("%.*s\n", vallen, val); 284 free(val); 285 key = outkey; 286 keylen = outkeylen; 287 288 if (err = yp_next(domain, map, key, keylen, &outkey, &outkeylen, 289 &val, &vallen)) { 290 291 if (err == YPERR_NOMORE) { 292 break; 293 } else { 294 (void) fprintf(stderr, err_next_failed, 295 yperr_string(err)); 296 exit(1); 297 } 298 } 299 300 free(key); 301 } 302 } 303 304 /* 305 * This gets the local default domainname, and makes sure that it's set 306 * to something reasonable. domain is set here. 307 */ 308 static void 309 getdomain() 310 { 311 if (!getdomainname(default_domain_name, YPMAXDOMAIN)) { 312 domain = default_domain_name; 313 } else { 314 (void) fprintf(stderr, err_cant_get_kname, err_bad_domainname); 315 exit(1); 316 } 317 318 if ((int)strlen(domain) == 0) { 319 (void) fprintf(stderr, err_null_kname, err_bad_domainname); 320 exit(1); 321 } 322 } 323