Update to 2.1.x development version
[glibc.git] / nis / ypclnt.c
blob6644118ac8cc0e74d8786c7898da61c4bf1bc327
1 /* Copyright (C) 1996 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
20 #include <string.h>
21 #include <unistd.h>
22 #include <fcntl.h>
23 #include <libc-lock.h>
24 #include <rpcsvc/yp.h>
25 #include <rpcsvc/ypclnt.h>
26 #include <rpcsvc/ypupd.h>
28 struct dom_binding
30 struct dom_binding *dom_pnext;
31 char dom_domain[YPMAXDOMAIN + 1];
32 struct sockaddr_in dom_server_addr;
33 int dom_socket;
34 CLIENT *dom_client;
35 long int dom_vers;
37 typedef struct dom_binding dom_binding;
39 static struct timeval TIMEOUT = {25, 0};
40 static int const MAXTRIES = 5;
41 static char __ypdomainname[MAXHOSTNAMELEN + 1] = "\0";
42 __libc_lock_define_initialized (static, ypbindlist_lock)
43 static dom_binding *__ypbindlist = NULL;
46 static int
47 __yp_bind (const char *domain, dom_binding ** ypdb)
49 struct sockaddr_in clnt_saddr;
50 struct ypbind_resp ypbr;
51 dom_binding *ysd;
52 int clnt_sock;
53 CLIENT *client;
54 int is_new = 0;
55 int try;
57 if (ypdb != NULL)
58 *ypdb = NULL;
60 if ((domain == NULL) || (strlen (domain) == 0))
61 return YPERR_BADARGS;
63 ysd = __ypbindlist;
64 while (ysd != NULL)
66 if (strcmp (domain, ysd->dom_domain) == 0)
67 break;
68 ysd = ysd->dom_pnext;
71 if (ysd == NULL)
73 is_new = 1;
74 ysd = (dom_binding *) malloc (sizeof *ysd);
75 memset (ysd, '\0', sizeof *ysd);
76 ysd->dom_socket = -1;
77 ysd->dom_vers = -1;
80 try = 0;
84 try++;
85 if (try > MAXTRIES)
87 if (is_new)
88 free (ysd);
89 return YPERR_YPBIND;
92 if (ysd->dom_vers == -1)
94 if(ysd->dom_client)
96 clnt_destroy(ysd->dom_client);
97 ysd->dom_client = NULL;
98 ysd->dom_socket = -1;
100 memset (&clnt_saddr, '\0', sizeof clnt_saddr);
101 clnt_saddr.sin_family = AF_INET;
102 clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
103 clnt_sock = RPC_ANYSOCK;
104 client = clnttcp_create (&clnt_saddr, YPBINDPROG, YPBINDVERS,
105 &clnt_sock, 0, 0);
106 if (client == NULL)
108 if (is_new)
109 free (ysd);
110 return YPERR_YPBIND;
113 ** Check the port number -- should be < IPPORT_RESERVED.
114 ** If not, it's possible someone has registered a bogus
115 ** ypbind with the portmapper and is trying to trick us.
117 if (ntohs(clnt_saddr.sin_port) >= IPPORT_RESERVED)
119 clnt_destroy(client);
120 if (is_new)
121 free(ysd);
122 return(YPERR_YPBIND);
125 if (clnt_call (client, YPBINDPROC_DOMAIN,
126 (xdrproc_t) xdr_domainname, &domain,
127 (xdrproc_t) xdr_ypbind_resp,
128 &ypbr, TIMEOUT) != RPC_SUCCESS)
130 clnt_destroy (client);
131 if (is_new)
132 free (ysd);
133 return YPERR_YPBIND;
136 clnt_destroy (client);
137 if (ypbr.ypbind_status != YPBIND_SUCC_VAL)
139 switch (ypbr.ypbind_resp_u.ypbind_error)
141 case YPBIND_ERR_ERR:
142 fputs (_("YPBINDPROC_DOMAIN: Internal error\n"), stderr);
143 break;
144 case YPBIND_ERR_NOSERV:
145 fprintf (stderr,
146 _("YPBINDPROC_DOMAIN: No server for domain %s\n"),
147 domain);
148 break;
149 case YPBIND_ERR_RESC:
150 fputs (_("YPBINDPROC_DOMAIN: Resource allocation failure\n"),
151 stderr);
152 break;
153 default:
154 fputs (_("YPBINDPROC_DOMAIN: Unknown error\n"), stderr);
155 break;
157 if (is_new)
158 free (ysd);
159 return YPERR_DOMAIN;
161 memset (&ysd->dom_server_addr, '\0', sizeof ysd->dom_server_addr);
162 ysd->dom_server_addr.sin_family = AF_INET;
163 memcpy (&ysd->dom_server_addr.sin_port,
164 ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port,
165 sizeof (ysd->dom_server_addr.sin_port));
166 memcpy (&ysd->dom_server_addr.sin_addr.s_addr,
167 ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
168 sizeof (ysd->dom_server_addr.sin_addr.s_addr));
169 ysd->dom_vers = YPVERS;
170 strcpy (ysd->dom_domain, domain);
173 if (ysd->dom_client)
174 clnt_destroy (ysd->dom_client);
175 ysd->dom_socket = RPC_ANYSOCK;
176 ysd->dom_client = clntudp_create (&ysd->dom_server_addr, YPPROG, YPVERS,
177 TIMEOUT, &ysd->dom_socket);
178 if (ysd->dom_client == NULL)
179 ysd->dom_vers = -1;
182 while (ysd->dom_client == NULL);
184 /* If the program exists, close the socket */
185 if (fcntl (ysd->dom_socket, F_SETFD, 1) == -1)
186 perror (_("fcntl: F_SETFD"));
188 if (is_new)
190 ysd->dom_pnext = __ypbindlist;
191 __ypbindlist = ysd;
194 if (NULL != ypdb)
195 *ypdb = ysd;
197 return YPERR_SUCCESS;
200 static void
201 __yp_unbind (dom_binding *ydb)
203 clnt_destroy (ydb->dom_client);
204 ydb->dom_client = NULL;
205 ydb->dom_socket = -1;
208 static int
209 do_ypcall (const char *domain, u_long prog, xdrproc_t xargs,
210 caddr_t req, xdrproc_t xres, caddr_t resp)
212 dom_binding *ydb = NULL;
213 int try, result;
215 try = 0;
216 result = YPERR_YPERR;
218 while (try < MAXTRIES && result != RPC_SUCCESS)
220 __libc_lock_lock (ypbindlist_lock);
222 if (__yp_bind (domain, &ydb) != 0)
224 __libc_lock_unlock (ypbindlist_lock);
225 return YPERR_DOMAIN;
228 result = clnt_call (ydb->dom_client, prog,
229 xargs, req, xres, resp, TIMEOUT);
231 if (result != RPC_SUCCESS)
233 clnt_perror (ydb->dom_client, "do_ypcall: clnt_call");
234 ydb->dom_vers = -1;
235 __yp_unbind (ydb);
236 result = YPERR_RPC;
239 __libc_lock_unlock (ypbindlist_lock);
241 try++;
244 return result;
248 yp_bind (const char *indomain)
250 int status;
252 __libc_lock_lock (ypbindlist_lock);
254 status = __yp_bind (indomain, NULL);
256 __libc_lock_unlock (ypbindlist_lock);
258 return status;
261 void
262 yp_unbind (const char *indomain)
264 dom_binding *ydbptr, *ydbptr2;
266 __libc_lock_lock (ypbindlist_lock);
268 ydbptr2 = NULL;
269 ydbptr = __ypbindlist;
270 while (ydbptr != NULL)
272 if (strcmp (ydbptr->dom_domain, indomain) == 0)
274 dom_binding *work;
276 work = ydbptr;
277 if (ydbptr2 == NULL)
278 __ypbindlist = __ypbindlist->dom_pnext;
279 else
280 ydbptr2 = ydbptr->dom_pnext;
281 __yp_unbind (work);
282 free (work);
283 break;
285 ydbptr2 = ydbptr;
286 ydbptr = ydbptr->dom_pnext;
289 __libc_lock_unlock (ypbindlist_lock);
291 return;
294 __libc_lock_define_initialized (static, domainname_lock)
297 yp_get_default_domain (char **outdomain)
299 int result = YPERR_SUCCESS;;
300 *outdomain = NULL;
302 __libc_lock_lock (domainname_lock);
304 if (__ypdomainname[0] == '\0')
306 if (getdomainname (__ypdomainname, MAXHOSTNAMELEN))
307 result = YPERR_NODOM;
308 else
309 *outdomain = __ypdomainname;
311 else
312 *outdomain = __ypdomainname;
314 __libc_lock_unlock (domainname_lock);
316 return result;
320 __yp_check (char **domain)
322 char *unused;
324 if (__ypdomainname[0] == '\0')
325 if (yp_get_default_domain (&unused))
326 return 0;
327 else if (strcmp (__ypdomainname, "(none)") == 0)
328 return 0;
330 if (domain)
331 *domain = __ypdomainname;
333 if (yp_bind (__ypdomainname) == 0)
334 return 1;
335 return 0;
339 yp_match (const char *indomain, const char *inmap, const char *inkey,
340 const int inkeylen, char **outval, int *outvallen)
342 ypreq_key req;
343 ypresp_val resp;
344 int result;
346 if (indomain == NULL || indomain[0] == '\0' ||
347 inmap == NULL || inmap[0] == '\0' ||
348 inkey == NULL || inkey[0] == '\0' || inkeylen <= 0)
349 return YPERR_BADARGS;
351 req.domain = (char *) indomain;
352 req.map = (char *) inmap;
353 req.key.keydat_val = (char *) inkey;
354 req.key.keydat_len = inkeylen;
356 *outval = NULL;
357 *outvallen = 0;
358 memset (&resp, '\0', sizeof (resp));
360 result = do_ypcall (indomain, YPPROC_MATCH, (xdrproc_t) xdr_ypreq_key,
361 (caddr_t) & req, (xdrproc_t) xdr_ypresp_val,
362 (caddr_t) & resp);
364 if (result != RPC_SUCCESS)
365 return result;
366 if (resp.stat != YP_TRUE)
367 return ypprot_err (resp.stat);
369 *outvallen = resp.val.valdat_len;
370 *outval = malloc (*outvallen + 1);
371 memcpy (*outval, resp.val.valdat_val, *outvallen);
372 (*outval)[*outvallen] = '\0';
374 xdr_free ((xdrproc_t) xdr_ypresp_val, (char *) &resp);
376 return YPERR_SUCCESS;
380 yp_first (const char *indomain, const char *inmap, char **outkey,
381 int *outkeylen, char **outval, int *outvallen)
383 ypreq_nokey req;
384 ypresp_key_val resp;
385 int result;
387 if (indomain == NULL || indomain[0] == '\0' ||
388 inmap == NULL || inmap[0] == '\0')
389 return YPERR_BADARGS;
391 req.domain = (char *) indomain;
392 req.map = (char *) inmap;
394 *outkey = *outval = NULL;
395 *outkeylen = *outvallen = 0;
396 memset (&resp, '\0', sizeof (resp));
398 result = do_ypcall (indomain, YPPROC_FIRST, (xdrproc_t) xdr_ypreq_nokey,
399 (caddr_t) & req, (xdrproc_t) xdr_ypresp_key_val,
400 (caddr_t) & resp);
402 if (result != RPC_SUCCESS)
403 return result;
404 if (resp.stat != YP_TRUE)
405 return ypprot_err (resp.stat);
407 *outkeylen = resp.key.keydat_len;
408 *outkey = malloc (*outkeylen + 1);
409 memcpy (*outkey, resp.key.keydat_val, *outkeylen);
410 (*outkey)[*outkeylen] = '\0';
411 *outvallen = resp.val.valdat_len;
412 *outval = malloc (*outvallen + 1);
413 memcpy (*outval, resp.val.valdat_val, *outvallen);
414 (*outval)[*outvallen] = '\0';
416 xdr_free ((xdrproc_t) xdr_ypresp_key_val, (char *) &resp);
418 return YPERR_SUCCESS;
422 yp_next (const char *indomain, const char *inmap, const char *inkey,
423 const int inkeylen, char **outkey, int *outkeylen, char **outval,
424 int *outvallen)
426 ypreq_key req;
427 ypresp_key_val resp;
428 int result;
430 if (indomain == NULL || indomain[0] == '\0' ||
431 inmap == NULL || inmap[0] == '\0' ||
432 inkeylen <= 0 || inkey == NULL || inkey[0] == '\0')
433 return YPERR_BADARGS;
435 req.domain = (char *) indomain;
436 req.map = (char *) inmap;
437 req.key.keydat_val = (char *) inkey;
438 req.key.keydat_len = inkeylen;
440 *outkey = *outval = NULL;
441 *outkeylen = *outvallen = 0;
442 memset (&resp, '\0', sizeof (resp));
444 result = do_ypcall (indomain, YPPROC_NEXT, (xdrproc_t) xdr_ypreq_key,
445 (caddr_t) & req, (xdrproc_t) xdr_ypresp_key_val,
446 (caddr_t) & resp);
448 if (result != RPC_SUCCESS)
449 return result;
450 if (resp.stat != YP_TRUE)
451 return ypprot_err (resp.stat);
453 *outkeylen = resp.key.keydat_len;
454 *outkey = malloc (*outkeylen + 1);
455 memcpy (*outkey, resp.key.keydat_val, *outkeylen);
456 (*outkey)[*outkeylen] = '\0';
457 *outvallen = resp.val.valdat_len;
458 *outval = malloc (*outvallen + 1);
459 memcpy (*outval, resp.val.valdat_val, *outvallen);
460 (*outval)[*outvallen] = '\0';
462 xdr_free ((xdrproc_t) xdr_ypresp_key_val, (char *) &resp);
464 return YPERR_SUCCESS;
468 yp_master (const char *indomain, const char *inmap, char **outname)
470 ypreq_nokey req;
471 ypresp_master resp;
472 int result;
474 if (indomain == NULL || indomain[0] == '\0' ||
475 inmap == NULL || inmap[0] == '\0')
476 return YPERR_BADARGS;
478 req.domain = (char *) indomain;
479 req.map = (char *) inmap;
481 memset (&resp, '\0', sizeof (ypresp_master));
483 result = do_ypcall (indomain, YPPROC_MASTER, (xdrproc_t) xdr_ypreq_nokey,
484 (caddr_t) & req, (xdrproc_t) xdr_ypresp_master, (caddr_t) & resp);
486 if (result != RPC_SUCCESS)
487 return result;
488 if (resp.stat != YP_TRUE)
489 return ypprot_err (resp.stat);
491 *outname = strdup (resp.peer);
492 xdr_free ((xdrproc_t) xdr_ypresp_master, (char *) &resp);
494 return YPERR_SUCCESS;
498 yp_order (const char *indomain, const char *inmap, unsigned int *outorder)
500 struct ypreq_nokey req;
501 struct ypresp_order resp;
502 int result;
504 if (indomain == NULL || indomain[0] == '\0' ||
505 inmap == NULL || inmap == '\0')
506 return YPERR_BADARGS;
508 req.domain = (char *) indomain;
509 req.map = (char *) inmap;
511 memset (&resp, '\0', sizeof (resp));
513 result = do_ypcall (indomain, YPPROC_ORDER, (xdrproc_t) xdr_ypreq_nokey,
514 (caddr_t) & req, (xdrproc_t) xdr_ypresp_order, (caddr_t) & resp);
516 if (result != RPC_SUCCESS)
517 return result;
518 if (resp.stat != YP_TRUE)
519 return ypprot_err (resp.stat);
521 *outorder = resp.ordernum;
522 xdr_free ((xdrproc_t) xdr_ypresp_order, (char *) &resp);
524 return YPERR_SUCCESS;
527 static void *ypall_data;
528 static int (*ypall_foreach) ();
530 static bool_t
531 __xdr_ypresp_all (XDR * xdrs, u_long * objp)
533 while (1)
535 struct ypresp_all resp;
537 memset (&resp, '\0', sizeof (struct ypresp_all));
538 if (!xdr_ypresp_all (xdrs, &resp))
540 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
541 *objp = YP_YPERR;
542 return (FALSE);
544 if (resp.more == 0)
546 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
547 *objp = YP_NOMORE;
548 return (FALSE);
551 switch (resp.ypresp_all_u.val.stat)
553 case YP_TRUE:
555 char key[resp.ypresp_all_u.val.key.keydat_len + 1];
556 char val[resp.ypresp_all_u.val.val.valdat_len + 1];
557 int keylen = resp.ypresp_all_u.val.key.keydat_len;
558 int vallen = resp.ypresp_all_u.val.val.valdat_len;
560 *objp = YP_TRUE;
561 memcpy (key, resp.ypresp_all_u.val.key.keydat_val, keylen);
562 key[keylen] = '\0';
563 memcpy (val, resp.ypresp_all_u.val.val.valdat_val, vallen);
564 val[vallen] = '\0';
565 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
566 if ((*ypall_foreach) (*objp, key, keylen,
567 val, vallen, ypall_data))
568 return TRUE;
570 break;
571 case YP_NOMORE:
572 *objp = YP_NOMORE;
573 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
574 return TRUE;
575 break;
576 default:
577 *objp = resp.ypresp_all_u.val.stat;
578 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
579 return TRUE;
585 yp_all (const char *indomain, const char *inmap,
586 const struct ypall_callback *incallback)
588 struct ypreq_nokey req;
589 dom_binding *ydb;
590 int try, result;
591 struct sockaddr_in clnt_sin;
592 CLIENT *clnt;
593 unsigned long status;
594 int clnt_sock;
596 if (indomain == NULL || indomain[0] == '\0' ||
597 inmap == NULL || inmap == '\0')
598 return YPERR_BADARGS;
600 try = 0;
601 result = YPERR_YPERR;
603 while (try < MAXTRIES && result != RPC_SUCCESS)
605 __libc_lock_lock (ypbindlist_lock);
607 if (__yp_bind (indomain, &ydb) != 0)
609 __libc_lock_unlock (ypbindlist_lock);
610 return YPERR_DOMAIN;
613 /* YPPROC_ALL get its own TCP channel to ypserv */
614 clnt_sock = RPC_ANYSOCK;
615 clnt_sin = ydb->dom_server_addr;
616 clnt_sin.sin_port = 0;
617 clnt = clnttcp_create (&clnt_sin, YPPROG, YPVERS, &clnt_sock, 0, 0);
618 if (clnt == NULL)
620 puts ("yp_all: clnttcp_create failed");
621 __libc_lock_unlock (ypbindlist_lock);
622 return YPERR_PMAP;
624 req.domain = (char *) indomain;
625 req.map = (char *) inmap;
627 ypall_foreach = incallback->foreach;
628 ypall_data = (void *) incallback->data;
630 result = clnt_call (clnt, YPPROC_ALL, (xdrproc_t) xdr_ypreq_nokey, &req,
631 (xdrproc_t) __xdr_ypresp_all, &status, TIMEOUT);
633 if (result != RPC_SUCCESS)
635 clnt_perror (ydb->dom_client, "yp_all: clnt_call");
636 clnt_destroy (clnt);
637 __yp_unbind (ydb);
638 result = YPERR_RPC;
640 else
642 clnt_destroy (clnt);
643 result = YPERR_SUCCESS;
646 __libc_lock_unlock (ypbindlist_lock);
648 if (status != YP_NOMORE)
649 return ypprot_err (status);
650 try++;
653 return result;
657 yp_maplist (const char *indomain, struct ypmaplist **outmaplist)
659 struct ypresp_maplist resp;
660 int result;
662 if (indomain == NULL || indomain[0] == '\0')
663 return YPERR_BADARGS;
665 memset (&resp, '\0', sizeof (resp));
667 result = do_ypcall (indomain, YPPROC_MAPLIST, (xdrproc_t) xdr_domainname,
668 (caddr_t) & indomain, (xdrproc_t) xdr_ypresp_maplist, (caddr_t) & resp);
670 if (result != RPC_SUCCESS)
671 return result;
672 if (resp.stat != YP_TRUE)
673 return ypprot_err (resp.stat);
675 *outmaplist = resp.maps;
676 /* We give the list not free, this will be done by ypserv
677 xdr_free((xdrproc_t)xdr_ypresp_maplist, (char *)&resp); */
679 return YPERR_SUCCESS;
682 const char *
683 yperr_string (const int error)
685 switch (error)
687 case YPERR_SUCCESS:
688 return _("Success");
689 case YPERR_BADARGS:
690 return _("Request arguments bad");
691 case YPERR_RPC:
692 return _("RPC failure on NIS operation");
693 case YPERR_DOMAIN:
694 return _("Can't bind to server which serves this domain");
695 case YPERR_MAP:
696 return _("No such map in server's domain");
697 case YPERR_KEY:
698 return _("No such key in map");
699 case YPERR_YPERR:
700 return _("Internal NIS error");
701 case YPERR_RESRC:
702 return _("Local resource allocation failure");
703 case YPERR_NOMORE:
704 return _("No more records in map database");
705 case YPERR_PMAP:
706 return _("Can't communicate with portmapper");
707 case YPERR_YPBIND:
708 return _("Can't communicate with ypbind");
709 case YPERR_YPSERV:
710 return _("Can't communicate with ypserv");
711 case YPERR_NODOM:
712 return _("Local domain name not set");
713 case YPERR_BADDB:
714 return _("NIS map data base is bad");
715 case YPERR_VERS:
716 return _("NIS client/server version mismatch - can't supply service");
717 case YPERR_ACCESS:
718 return _("Permission denied");
719 case YPERR_BUSY:
720 return _("Database is busy");
722 return _("Unknown NIS error code");
726 ypprot_err (const int code)
728 switch (code)
730 case YP_TRUE:
731 return YPERR_SUCCESS;
732 case YP_NOMORE:
733 return YPERR_NOMORE;
734 case YP_FALSE:
735 return YPERR_YPERR;
736 case YP_NOMAP:
737 return YPERR_MAP;
738 case YP_NODOM:
739 return YPERR_DOMAIN;
740 case YP_NOKEY:
741 return YPERR_KEY;
742 case YP_BADOP:
743 return YPERR_YPERR;
744 case YP_BADDB:
745 return YPERR_BADDB;
746 case YP_YPERR:
747 return YPERR_YPERR;
748 case YP_BADARGS:
749 return YPERR_BADARGS;
750 case YP_VERS:
751 return YPERR_VERS;
753 return YPERR_YPERR;
756 const char *
757 ypbinderr_string (const int error)
759 switch (error)
761 case 0:
762 return _("Success");
763 case YPBIND_ERR_ERR:
764 return _("Internal ypbind error");
765 case YPBIND_ERR_NOSERV:
766 return _("Domain not bound");
767 case YPBIND_ERR_RESC:
768 return _("System resource allocation failure");
769 default:
770 return _("Unknown ypbind error");
775 #define WINDOW 60
778 yp_update (char *domain, char *map, unsigned ypop,
779 char *key, int keylen, char *data, int datalen)
781 #if 0
782 union
784 ypupdate_args update_args;
785 ypdelete_args delete_args;
787 args;
788 xdrproc_t xdr_argument;
789 unsigned res = 0;
790 CLIENT *clnt;
791 char *master;
792 struct sockaddr saddr;
793 char servername[MAXNETNAMELEN + 1];
794 int r;
796 if (!domain || !map || !key || (ypop != YPOP_DELETE && !data))
797 return YPERR_BADARGS;
799 args.update_args.mapname = map;
800 args.update_args.key.yp_buf_len = keylen;
801 args.update_args.key.yp_buf_val = key;
802 args.update_args.datum.yp_buf_len = datalen;
803 args.update_args.datum.yp_buf_val = data;
805 if ((r = yp_master (domain, map, &master)) != 0)
806 return r;
808 if (!host2netname (servername, master, domain))
810 fputs (_("yp_update: cannot convert host to netname\n"), stderr);
811 return YPERR_YPERR;
814 if ((clnt = clnt_create (master, YPU_PROG, YPU_VERS, "tcp")) == NULL)
816 clnt_pcreateerror ("yp_update: clnt_create");
817 return YPERR_RPC;
820 if (!clnt_control (clnt, CLGET_SERVER_ADDR, (char *) &saddr))
822 fputs (_("yp_update: cannot get server address\n"), stderr);
823 return YPERR_RPC;
826 switch (ypop)
828 case YPOP_CHANGE:
829 case YPOP_INSERT:
830 case YPOP_STORE:
831 xdr_argument = (xdrproc_t) xdr_ypupdate_args;
832 break;
833 case YPOP_DELETE:
834 xdr_argument = (xdrproc_t) xdr_ypdelete_args;
835 break;
836 default:
837 return YPERR_BADARGS;
838 break;
841 clnt->cl_auth = authdes_create (servername, WINDOW, &saddr, NULL);
843 if (clnt->cl_auth == NULL)
844 clnt->cl_auth = authunix_create_default ();
846 again:
847 r = clnt_call (clnt, ypop, xdr_argument, &args,
848 (xdrproc_t) xdr_u_int, &res, TIMEOUT);
850 if (r == RPC_AUTHERROR)
852 if (clnt->cl_auth->ah_cred.oa_flavor == AUTH_DES)
854 clnt->cl_auth = authunix_create_default ();
855 goto again;
857 else
858 return YPERR_ACCESS;
860 if (r != RPC_SUCCESS)
862 clnt_perror (clnt, "yp_update: clnt_call");
863 return YPERR_RPC;
865 return res;
866 #else
867 return YPERR_YPERR;
868 #endif