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