1 /* 2 * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@fsa.ca> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Theo de Raadt. 16 * 4. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 20 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #ifndef LINT 33 static char *rcsid = "$Id: yplib.c,v 1.10 1994/08/18 00:45:07 mycroft Exp $"; 34 #endif 35 36 #include <sys/param.h> 37 #include <sys/types.h> 38 #include <sys/socket.h> 39 #include <sys/file.h> 40 #include <sys/uio.h> 41 #include <errno.h> 42 #include <stdio.h> 43 #include <stdlib.h> 44 #include <string.h> 45 #include <unistd.h> 46 #include <rpc/rpc.h> 47 #include <rpc/xdr.h> 48 #include <rpcsvc/yp_prot.h> 49 #include <rpcsvc/ypclnt.h> 50 51 #ifndef BINDINGDIR 52 #define BINDINGDIR "/var/yp/binding" 53 #endif 54 #define YPMATCHCACHE 55 56 extern bool_t xdr_domainname(), xdr_ypbind_resp(); 57 extern bool_t xdr_ypreq_key(), xdr_ypresp_val(); 58 extern bool_t xdr_ypreq_nokey(), xdr_ypresp_key_val(); 59 extern bool_t xdr_ypresp_all(), xdr_ypresp_all_seq(); 60 extern bool_t xdr_ypresp_master(); 61 62 int (*ypresp_allfn)(); 63 void *ypresp_data; 64 65 struct dom_binding *_ypbindlist; 66 static char _yp_domain[MAXHOSTNAMELEN]; 67 int _yplib_timeout = 10; 68 69 #ifdef YPMATCHCACHE 70 int _yplib_cache = 5; 71 72 static struct ypmatch_ent { 73 struct ypmatch_ent *next; 74 char *map, *key, *val; 75 int keylen, vallen; 76 time_t expire_t; 77 } *ypmc; 78 79 static void 80 ypmatch_add(map, key, keylen, val, vallen) 81 char *map; 82 char *key; 83 int keylen; 84 char *val; 85 int vallen; 86 { 87 struct ypmatch_ent *ep; 88 time_t t; 89 90 time(&t); 91 92 for(ep=ypmc; ep; ep=ep->next) 93 if(ep->expire_t < t) 94 break; 95 if(ep==NULL) { 96 ep = (struct ypmatch_ent *)malloc(sizeof *ep); 97 memset(ep, 0, sizeof *ep); 98 if(ypmc) 99 ep->next = ypmc; 100 ypmc = ep; 101 } 102 103 if(ep->key) 104 free(ep->key); 105 if(ep->val) 106 free(ep->val); 107 108 ep->key = NULL; 109 ep->val = NULL; 110 111 ep->key = (char *)malloc(keylen); 112 if(ep->key==NULL) 113 return; 114 115 ep->val = (char *)malloc(vallen); 116 if(ep->key==NULL) { 117 free(ep->key); 118 ep->key = NULL; 119 return; 120 } 121 ep->keylen = keylen; 122 ep->vallen = vallen; 123 124 memcpy(ep->key, key, ep->keylen); 125 memcpy(ep->val, val, ep->vallen); 126 127 if(ep->map) { 128 if( strcmp(ep->map, map) ) { 129 free(ep->map); 130 ep->map = strdup(map); 131 } 132 } else { 133 ep->map = strdup(map); 134 } 135 136 ep->expire_t = t + _yplib_cache; 137 } 138 139 static bool_t 140 ypmatch_find(map, key, keylen, val, vallen) 141 char *map; 142 char *key; 143 int keylen; 144 char **val; 145 int *vallen; 146 { 147 struct ypmatch_ent *ep; 148 time_t t; 149 150 if(ypmc==NULL) 151 return 0; 152 153 time(&t); 154 155 for(ep=ypmc; ep; ep=ep->next) { 156 if(ep->keylen != keylen) 157 continue; 158 if(strcmp(ep->map, map)) 159 continue; 160 if(memcmp(ep->key, key, keylen)) 161 continue; 162 if(t > ep->expire_t) 163 continue; 164 165 *val = ep->val; 166 *vallen = ep->vallen; 167 return 1; 168 } 169 return 0; 170 } 171 #endif 172 173 int 174 _yp_dobind(dom, ypdb) 175 char *dom; 176 struct dom_binding **ypdb; 177 { 178 static int pid = -1; 179 char path[MAXPATHLEN]; 180 struct dom_binding *ysd, *ysd2; 181 struct ypbind_resp ypbr; 182 struct timeval tv; 183 struct sockaddr_in clnt_sin; 184 int clnt_sock, fd, gpid; 185 CLIENT *client; 186 int new=0, r; 187 188 gpid = getpid(); 189 if( !(pid==-1 || pid==gpid) ) { 190 ysd = _ypbindlist; 191 while(ysd) { 192 if(ysd->dom_client) 193 clnt_destroy(ysd->dom_client); 194 ysd2 = ysd->dom_pnext; 195 free(ysd); 196 ysd = ysd2; 197 } 198 _ypbindlist = NULL; 199 } 200 pid = gpid; 201 202 if(ypdb!=NULL) 203 *ypdb = NULL; 204 205 if(dom==NULL || strlen(dom)==0) 206 return YPERR_BADARGS; 207 208 for(ysd = _ypbindlist; ysd; ysd = ysd->dom_pnext) 209 if( strcmp(dom, ysd->dom_domain) == 0) 210 break; 211 if(ysd==NULL) { 212 ysd = (struct dom_binding *)malloc(sizeof *ysd); 213 memset(ysd, 0, sizeof *ysd); 214 ysd->dom_socket = -1; 215 ysd->dom_vers = 0; 216 new = 1; 217 } 218 again: 219 #ifdef BINDINGDIR 220 if(ysd->dom_vers==0) { 221 sprintf(path, "%s/%s.%d", BINDINGDIR, dom, 2); 222 if( (fd=open(path, O_RDONLY)) == -1) { 223 /* no binding file, YP is dead. */ 224 if(new) 225 free(ysd); 226 return YPERR_YPBIND; 227 } 228 if( flock(fd, LOCK_EX|LOCK_NB) == -1 && errno==EWOULDBLOCK) { 229 struct iovec iov[2]; 230 struct ypbind_resp ybr; 231 u_short ypb_port; 232 233 iov[0].iov_base = (caddr_t)&ypb_port; 234 iov[0].iov_len = sizeof ypb_port; 235 iov[1].iov_base = (caddr_t)&ybr; 236 iov[1].iov_len = sizeof ybr; 237 238 r = readv(fd, iov, 2); 239 if(r != iov[0].iov_len + iov[1].iov_len) { 240 close(fd); 241 ysd->dom_vers = -1; 242 goto again; 243 } 244 245 memset(&ysd->dom_server_addr, 0, sizeof ysd->dom_server_addr); 246 ysd->dom_server_addr.sin_family = AF_INET; 247 ysd->dom_server_addr.sin_len = sizeof(struct sockaddr_in); 248 ysd->dom_server_addr.sin_addr = 249 ybr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr; 250 ysd->dom_server_addr.sin_port = 251 ybr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_port; 252 253 ysd->dom_server_port = ysd->dom_server_addr.sin_port; 254 close(fd); 255 goto gotit; 256 } else { 257 /* no lock on binding file, YP is dead. */ 258 close(fd); 259 if(new) 260 free(ysd); 261 return YPERR_YPBIND; 262 } 263 } 264 #endif 265 if(ysd->dom_vers==-1 || ysd->dom_vers==0) { 266 memset(&clnt_sin, 0, sizeof clnt_sin); 267 clnt_sin.sin_family = AF_INET; 268 clnt_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 269 270 clnt_sock = RPC_ANYSOCK; 271 client = clnttcp_create(&clnt_sin, YPBINDPROG, YPBINDVERS, &clnt_sock, 272 0, 0); 273 if(client==NULL) { 274 clnt_pcreateerror("clnttcp_create"); 275 if(new) 276 free(ysd); 277 return YPERR_YPBIND; 278 } 279 280 tv.tv_sec = _yplib_timeout; 281 tv.tv_usec = 0; 282 r = clnt_call(client, YPBINDPROC_DOMAIN, 283 xdr_domainname, dom, xdr_ypbind_resp, &ypbr, tv); 284 if(r != RPC_SUCCESS) { 285 fprintf(stderr, 286 "YP: server for domain %s not responding, still trying\n", dom); 287 clnt_destroy(client); 288 ysd->dom_vers = -1; 289 goto again; 290 } 291 clnt_destroy(client); 292 293 memset(&ysd->dom_server_addr, 0, sizeof ysd->dom_server_addr); 294 ysd->dom_server_addr.sin_family = AF_INET; 295 ysd->dom_server_addr.sin_port = 296 ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_port; 297 ysd->dom_server_addr.sin_addr.s_addr = 298 ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr.s_addr; 299 ysd->dom_server_port = 300 ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_port; 301 gotit: 302 ysd->dom_vers = YPVERS; 303 strcpy(ysd->dom_domain, dom); 304 } 305 306 tv.tv_sec = _yplib_timeout/2; 307 tv.tv_usec = 0; 308 if(ysd->dom_client) 309 clnt_destroy(ysd->dom_client); 310 ysd->dom_socket = RPC_ANYSOCK; 311 ysd->dom_client = clntudp_create(&ysd->dom_server_addr, 312 YPPROG, YPVERS, tv, &ysd->dom_socket); 313 if(ysd->dom_client==NULL) { 314 clnt_pcreateerror("clntudp_create"); 315 ysd->dom_vers = -1; 316 goto again; 317 } 318 if( fcntl(ysd->dom_socket, F_SETFD, 1) == -1) 319 perror("fcntl: F_SETFD"); 320 321 if(new) { 322 ysd->dom_pnext = _ypbindlist; 323 _ypbindlist = ysd; 324 } 325 326 if(ypdb!=NULL) 327 *ypdb = ysd; 328 return 0; 329 } 330 331 static void 332 _yp_unbind(ypb) 333 struct dom_binding *ypb; 334 { 335 clnt_destroy(ypb->dom_client); 336 ypb->dom_client = NULL; 337 ypb->dom_socket = -1; 338 } 339 340 int 341 yp_bind(dom) 342 char *dom; 343 { 344 return _yp_dobind(dom, NULL); 345 } 346 347 void 348 yp_unbind(dom) 349 char *dom; 350 { 351 struct dom_binding *ypb, *ypbp; 352 353 ypbp = NULL; 354 for(ypb=_ypbindlist; ypb; ypb=ypb->dom_pnext) { 355 if( strcmp(dom, ypb->dom_domain) == 0) { 356 clnt_destroy(ypb->dom_client); 357 if(ypbp) 358 ypbp->dom_pnext = ypb->dom_pnext; 359 else 360 _ypbindlist = ypb->dom_pnext; 361 free(ypb); 362 return; 363 } 364 ypbp = ypb; 365 } 366 return; 367 } 368 369 int 370 yp_match(indomain, inmap, inkey, inkeylen, outval, outvallen) 371 char *indomain; 372 char *inmap; 373 const char *inkey; 374 int inkeylen; 375 char **outval; 376 int *outvallen; 377 { 378 struct dom_binding *ysd; 379 struct ypresp_val yprv; 380 struct timeval tv; 381 struct ypreq_key yprk; 382 int r; 383 384 *outval = NULL; 385 *outvallen = 0; 386 387 again: 388 if( _yp_dobind(indomain, &ysd) != 0) 389 return YPERR_DOMAIN; 390 391 #ifdef YPMATCHCACHE 392 if( !strcmp(_yp_domain, indomain) && ypmatch_find(inmap, inkey, 393 inkeylen, &yprv.valdat.dptr, &yprv.valdat.dsize)) { 394 *outvallen = yprv.valdat.dsize; 395 *outval = (char *)malloc(*outvallen+1); 396 memcpy(*outval, yprv.valdat.dptr, *outvallen); 397 (*outval)[*outvallen] = '\0'; 398 return 0; 399 } 400 #endif 401 402 tv.tv_sec = _yplib_timeout; 403 tv.tv_usec = 0; 404 405 yprk.domain = indomain; 406 yprk.map = inmap; 407 yprk.keydat.dptr = (char *)inkey; 408 yprk.keydat.dsize = inkeylen; 409 410 memset(&yprv, 0, sizeof yprv); 411 412 r = clnt_call(ysd->dom_client, YPPROC_MATCH, 413 xdr_ypreq_key, &yprk, xdr_ypresp_val, &yprv, tv); 414 if(r != RPC_SUCCESS) { 415 clnt_perror(ysd->dom_client, "yp_match: clnt_call"); 416 ysd->dom_vers = -1; 417 goto again; 418 } 419 if( !(r=ypprot_err(yprv.status)) ) { 420 *outvallen = yprv.valdat.dsize; 421 *outval = (char *)malloc(*outvallen+1); 422 memcpy(*outval, yprv.valdat.dptr, *outvallen); 423 (*outval)[*outvallen] = '\0'; 424 #ifdef YPMATCHCACHE 425 if( strcmp(_yp_domain, indomain)==0 ) 426 ypmatch_add(inmap, inkey, inkeylen, *outval, *outvallen); 427 #endif 428 } 429 xdr_free(xdr_ypresp_val, (char *)&yprv); 430 _yp_unbind(ysd); 431 return r; 432 } 433 434 int 435 yp_get_default_domain(domp) 436 char **domp; 437 { 438 *domp = NULL; 439 if(_yp_domain[0] == '\0') 440 if( getdomainname(_yp_domain, sizeof _yp_domain)) 441 return YPERR_NODOM; 442 *domp = _yp_domain; 443 return 0; 444 } 445 446 int 447 yp_first(indomain, inmap, outkey, outkeylen, outval, outvallen) 448 char *indomain; 449 char *inmap; 450 char **outkey; 451 int *outkeylen; 452 char **outval; 453 int *outvallen; 454 { 455 struct ypresp_key_val yprkv; 456 struct ypreq_nokey yprnk; 457 struct dom_binding *ysd; 458 struct timeval tv; 459 int r; 460 461 *outkey = *outval = NULL; 462 *outkeylen = *outvallen = 0; 463 464 again: 465 if( _yp_dobind(indomain, &ysd) != 0) 466 return YPERR_DOMAIN; 467 468 tv.tv_sec = _yplib_timeout; 469 tv.tv_usec = 0; 470 471 yprnk.domain = indomain; 472 yprnk.map = inmap; 473 memset(&yprkv, 0, sizeof yprkv); 474 475 r = clnt_call(ysd->dom_client, YPPROC_FIRST, 476 xdr_ypreq_nokey, &yprnk, xdr_ypresp_key_val, &yprkv, tv); 477 if(r != RPC_SUCCESS) { 478 clnt_perror(ysd->dom_client, "yp_first: clnt_call"); 479 ysd->dom_vers = -1; 480 goto again; 481 } 482 if( !(r=ypprot_err(yprkv.status)) ) { 483 *outkeylen = yprkv.keydat.dsize; 484 *outkey = (char *)malloc(*outkeylen+1); 485 memcpy(*outkey, yprkv.keydat.dptr, *outkeylen); 486 (*outkey)[*outkeylen] = '\0'; 487 *outvallen = yprkv.valdat.dsize; 488 *outval = (char *)malloc(*outvallen+1); 489 memcpy(*outval, yprkv.valdat.dptr, *outvallen); 490 (*outval)[*outvallen] = '\0'; 491 } 492 xdr_free(xdr_ypresp_key_val, (char *)&yprkv); 493 _yp_unbind(ysd); 494 return r; 495 } 496 497 int 498 yp_next(indomain, inmap, inkey, inkeylen, outkey, outkeylen, outval, outvallen) 499 char *indomain; 500 char *inmap; 501 char *inkey; 502 int inkeylen; 503 char **outkey; 504 int *outkeylen; 505 char **outval; 506 int *outvallen; 507 { 508 struct ypresp_key_val yprkv; 509 struct ypreq_key yprk; 510 struct dom_binding *ysd; 511 struct timeval tv; 512 int r; 513 514 *outkey = *outval = NULL; 515 *outkeylen = *outvallen = 0; 516 517 again: 518 if( _yp_dobind(indomain, &ysd) != 0) 519 return YPERR_DOMAIN; 520 521 tv.tv_sec = _yplib_timeout; 522 tv.tv_usec = 0; 523 524 yprk.domain = indomain; 525 yprk.map = inmap; 526 yprk.keydat.dptr = inkey; 527 yprk.keydat.dsize = inkeylen; 528 memset(&yprkv, 0, sizeof yprkv); 529 530 r = clnt_call(ysd->dom_client, YPPROC_NEXT, 531 xdr_ypreq_key, &yprk, xdr_ypresp_key_val, &yprkv, tv); 532 if(r != RPC_SUCCESS) { 533 clnt_perror(ysd->dom_client, "yp_next: clnt_call"); 534 ysd->dom_vers = -1; 535 goto again; 536 } 537 if( !(r=ypprot_err(yprkv.status)) ) { 538 *outkeylen = yprkv.keydat.dsize; 539 *outkey = (char *)malloc(*outkeylen+1); 540 memcpy(*outkey, yprkv.keydat.dptr, *outkeylen); 541 (*outkey)[*outkeylen] = '\0'; 542 *outvallen = yprkv.valdat.dsize; 543 *outval = (char *)malloc(*outvallen+1); 544 memcpy(*outval, yprkv.valdat.dptr, *outvallen); 545 (*outval)[*outvallen] = '\0'; 546 } 547 xdr_free(xdr_ypresp_key_val, (char *)&yprkv); 548 _yp_unbind(ysd); 549 return r; 550 } 551 552 int 553 yp_all(indomain, inmap, incallback) 554 char *indomain; 555 char *inmap; 556 struct ypall_callback *incallback; 557 { 558 struct ypreq_nokey yprnk; 559 struct dom_binding *ysd; 560 struct timeval tv; 561 struct sockaddr_in clnt_sin; 562 CLIENT *clnt; 563 u_long status; 564 int clnt_sock; 565 566 if( _yp_dobind(indomain, &ysd) != 0) 567 return YPERR_DOMAIN; 568 569 tv.tv_sec = _yplib_timeout; 570 tv.tv_usec = 0; 571 clnt_sock = RPC_ANYSOCK; 572 clnt_sin = ysd->dom_server_addr; 573 clnt_sin.sin_port = 0; 574 clnt = clnttcp_create(&clnt_sin, YPPROG, YPVERS, &clnt_sock, 0, 0); 575 if(clnt==NULL) { 576 printf("clnttcp_create failed\n"); 577 return YPERR_PMAP; 578 } 579 580 yprnk.domain = indomain; 581 yprnk.map = inmap; 582 ypresp_allfn = incallback->foreach; 583 ypresp_data = (void *)incallback->data; 584 585 (void) clnt_call(clnt, YPPROC_ALL, 586 xdr_ypreq_nokey, &yprnk, xdr_ypresp_all_seq, &status, tv); 587 clnt_destroy(clnt); 588 xdr_free(xdr_ypresp_all_seq, (char *)&status); /* not really needed... */ 589 _yp_unbind(ysd); 590 591 if(status != YP_FALSE) 592 return ypprot_err(status); 593 return 0; 594 } 595 596 int 597 yp_order(indomain, inmap, outorder) 598 char *indomain; 599 char *inmap; 600 int *outorder; 601 { 602 struct dom_binding *ysd; 603 struct ypresp_order ypro; 604 struct ypreq_nokey yprnk; 605 struct timeval tv; 606 int r; 607 608 again: 609 if( _yp_dobind(indomain, &ysd) != 0) 610 return YPERR_DOMAIN; 611 612 tv.tv_sec = _yplib_timeout; 613 tv.tv_usec = 0; 614 615 yprnk.domain = indomain; 616 yprnk.map = inmap; 617 618 memset(&ypro, 0, sizeof ypro); 619 620 r = clnt_call(ysd->dom_client, YPPROC_ORDER, 621 xdr_ypreq_nokey, &yprnk, xdr_ypresp_order, &ypro, tv); 622 if(r != RPC_SUCCESS) { 623 clnt_perror(ysd->dom_client, "yp_order: clnt_call"); 624 ysd->dom_vers = -1; 625 goto again; 626 } 627 628 *outorder = ypro.ordernum; 629 xdr_free(xdr_ypresp_order, (char *)&ypro); 630 _yp_unbind(ysd); 631 return ypprot_err(ypro.status); 632 } 633 634 int 635 yp_master(indomain, inmap, outname) 636 char *indomain; 637 char *inmap; 638 char **outname; 639 { 640 struct dom_binding *ysd; 641 struct ypresp_master yprm; 642 struct ypreq_nokey yprnk; 643 struct timeval tv; 644 int r; 645 646 again: 647 if( _yp_dobind(indomain, &ysd) != 0) 648 return YPERR_DOMAIN; 649 650 tv.tv_sec = _yplib_timeout; 651 tv.tv_usec = 0; 652 653 yprnk.domain = indomain; 654 yprnk.map = inmap; 655 656 memset(&yprm, 0, sizeof yprm); 657 658 r = clnt_call(ysd->dom_client, YPPROC_MASTER, 659 xdr_ypreq_nokey, &yprnk, xdr_ypresp_master, &yprm, tv); 660 if(r != RPC_SUCCESS) { 661 clnt_perror(ysd->dom_client, "yp_master: clnt_call"); 662 ysd->dom_vers = -1; 663 goto again; 664 } 665 if( !(r=ypprot_err(yprm.status)) ) { 666 *outname = (char *)strdup(yprm.master); 667 } 668 xdr_free(xdr_ypresp_master, (char *)&yprm); 669 _yp_unbind(ysd); 670 return r; 671 } 672 673 yp_maplist(indomain, outmaplist) 674 char *indomain; 675 struct ypmaplist **outmaplist; 676 { 677 struct dom_binding *ysd; 678 struct ypresp_maplist ypml; 679 struct timeval tv; 680 int r; 681 682 again: 683 if( _yp_dobind(indomain, &ysd) != 0) 684 return YPERR_DOMAIN; 685 686 tv.tv_sec = _yplib_timeout; 687 tv.tv_usec = 0; 688 689 memset(&ypml, 0, sizeof ypml); 690 691 r = clnt_call(ysd->dom_client, YPPROC_MAPLIST, 692 xdr_domainname, indomain, xdr_ypresp_maplist, &ypml, tv); 693 if (r != RPC_SUCCESS) { 694 clnt_perror(ysd->dom_client, "yp_maplist: clnt_call"); 695 ysd->dom_vers = -1; 696 goto again; 697 } 698 *outmaplist = ypml.list; 699 /* NO: xdr_free(xdr_ypresp_maplist, &ypml);*/ 700 _yp_unbind(ysd); 701 return ypprot_err(ypml.status); 702 } 703 704 char * 705 yperr_string(incode) 706 int incode; 707 { 708 static char err[80]; 709 710 switch(incode) { 711 case 0: 712 return "Success"; 713 case YPERR_BADARGS: 714 return "Request arguments bad"; 715 case YPERR_RPC: 716 return "RPC failure"; 717 case YPERR_DOMAIN: 718 return "Can't bind to server which serves this domain"; 719 case YPERR_MAP: 720 return "No such map in server's domain"; 721 case YPERR_KEY: 722 return "No such key in map"; 723 case YPERR_YPERR: 724 return "YP server error"; 725 case YPERR_RESRC: 726 return "Local resource allocation failure"; 727 case YPERR_NOMORE: 728 return "No more records in map database"; 729 case YPERR_PMAP: 730 return "Can't communicate with portmapper"; 731 case YPERR_YPBIND: 732 return "Can't communicate with ypbind"; 733 case YPERR_YPSERV: 734 return "Can't communicate with ypserv"; 735 case YPERR_NODOM: 736 return "Local domain name not set"; 737 case YPERR_BADDB: 738 return "Server data base is bad"; 739 case YPERR_VERS: 740 return "YP server version mismatch - server can't supply service."; 741 case YPERR_ACCESS: 742 return "Access violation"; 743 case YPERR_BUSY: 744 return "Database is busy"; 745 } 746 sprintf(err, "YP unknown error %d\n", incode); 747 return err; 748 } 749 750 int 751 ypprot_err(incode) 752 unsigned int incode; 753 { 754 switch(incode) { 755 case YP_TRUE: 756 return 0; 757 case YP_FALSE: 758 return YPERR_YPBIND; 759 case YP_NOMORE: 760 return YPERR_NOMORE; 761 case YP_NOMAP: 762 return YPERR_MAP; 763 case YP_NODOM: 764 return YPERR_NODOM; 765 case YP_NOKEY: 766 return YPERR_KEY; 767 case YP_BADOP: 768 return YPERR_YPERR; 769 case YP_BADDB: 770 return YPERR_BADDB; 771 case YP_YPERR: 772 return YPERR_YPERR; 773 case YP_BADARGS: 774 return YPERR_BADARGS; 775 case YP_VERS: 776 return YPERR_VERS; 777 } 778 return YPERR_YPERR; 779 } 780 781 int 782 _yp_check(dom) 783 char **dom; 784 { 785 int use_yp = 0; 786 char *unused; 787 788 if( _yp_domain[0]=='\0' ) 789 if( yp_get_default_domain(&unused) ) 790 return 0; 791 792 if(dom) 793 *dom = _yp_domain; 794 795 if( yp_bind(_yp_domain)==0 ) 796 return 1; 797 return 0; 798 } 799