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