1 /* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Thorsten Kukuk <kukuk@suse.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. */
26 #include <rpcsvc/nis.h>
27 #include <rpcsvc/yp.h>
28 #include <rpcsvc/ypclnt.h>
29 #include <rpcsvc/ypupd.h>
31 #include <bits/libc-lock.h>
33 /* This should only be defined on systems with a BSD compatible ypbind */
35 # define BINDINGDIR "/var/yp/binding"
40 struct dom_binding
*dom_pnext
;
41 char dom_domain
[YPMAXDOMAIN
+ 1];
42 struct sockaddr_in dom_server_addr
;
46 typedef struct dom_binding dom_binding
;
48 static struct timeval RPCTIMEOUT
= {25, 0};
49 static struct timeval UDPTIMEOUT
= {5, 0};
50 static int const MAXTRIES
= 2;
51 static char __ypdomainname
[NIS_MAXNAMELEN
+ 1] = "\0";
52 __libc_lock_define_initialized (static, ypbindlist_lock
)
53 static dom_binding
*__ypbindlist
= NULL
;
57 __yp_bind (const char *domain
, dom_binding
**ypdb
)
59 struct sockaddr_in clnt_saddr
;
60 struct ypbind_resp ypbr
;
61 dom_binding
*ysd
= NULL
;
66 if (domain
== NULL
|| domain
[0] == '\0')
74 if (strcmp (domain
, ysd
->dom_domain
) == 0)
83 ysd
= (dom_binding
*) calloc (1, sizeof *ysd
);
87 if (ysd
->dom_client
== NULL
)
89 /* Try binding dir at first if we have no binding */
90 char path
[sizeof (BINDINGDIR
) + strlen (domain
) + 10];
95 sprintf (path
, "%s/%s.%d", BINDINGDIR
, domain
, YPBINDVERS
);
96 fd
= open (path
, O_RDONLY
);
99 /* We have a binding file and could save a RPC call */
100 vec
[0].iov_base
= &port
;
101 vec
[0].iov_len
= sizeof (port
);
102 vec
[1].iov_base
= &ypbr
;
103 vec
[1].iov_len
= sizeof (ypbr
);
105 if (readv (fd
, vec
, 2) == sizeof (port
) + sizeof (ypbr
))
107 ysd
->dom_server_addr
.sin_family
= AF_INET
;
108 memcpy (&ysd
->dom_server_addr
.sin_port
,
109 ypbr
.ypbind_resp_u
.ypbind_bindinfo
.ypbind_binding_port
,
110 sizeof (ysd
->dom_server_addr
.sin_port
));
111 memcpy (&ysd
->dom_server_addr
.sin_addr
.s_addr
,
112 ypbr
.ypbind_resp_u
.ypbind_bindinfo
.ypbind_binding_addr
,
113 sizeof (ysd
->dom_server_addr
.sin_addr
.s_addr
));
114 strncpy (ysd
->dom_domain
, domain
, YPMAXDOMAIN
);
115 ysd
->dom_domain
[YPMAXDOMAIN
] = '\0';
117 ysd
->dom_socket
= RPC_ANYSOCK
;
118 ysd
->dom_client
= clntudp_create (&ysd
->dom_server_addr
, YPPROG
,
122 if (ysd
->dom_client
!= NULL
)
123 /* If the program exits, close the socket */
124 if (fcntl (ysd
->dom_socket
, F_SETFD
, 1) == -1)
125 perror ("fcntl: F_SETFD");
130 #endif /* USE_BINDINGDIR */
132 if (ysd
->dom_client
== NULL
)
134 memset (&clnt_saddr
, '\0', sizeof clnt_saddr
);
135 clnt_saddr
.sin_family
= AF_INET
;
136 clnt_saddr
.sin_addr
.s_addr
= htonl (INADDR_LOOPBACK
);
137 clnt_sock
= RPC_ANYSOCK
;
138 client
= clnttcp_create (&clnt_saddr
, YPBINDPROG
, YPBINDVERS
,
146 /* Check the port number -- should be < IPPORT_RESERVED.
147 If not, it's possible someone has registered a bogus
148 ypbind with the portmapper and is trying to trick us. */
149 if (ntohs (clnt_saddr
.sin_port
) >= IPPORT_RESERVED
)
151 clnt_destroy (client
);
157 if (clnt_call (client
, YPBINDPROC_DOMAIN
,
158 (xdrproc_t
) xdr_domainname
, (caddr_t
) &domain
,
159 (xdrproc_t
) xdr_ypbind_resp
,
160 (caddr_t
) &ypbr
, RPCTIMEOUT
) != RPC_SUCCESS
)
162 clnt_destroy (client
);
168 clnt_destroy (client
);
170 if (ypbr
.ypbind_status
!= YPBIND_SUCC_VAL
)
172 fprintf (stderr
, _("YPBINDPROC_DOMAIN: %s\n"),
173 ypbinderr_string (ypbr
.ypbind_resp_u
.ypbind_error
));
178 memset (&ysd
->dom_server_addr
, '\0', sizeof ysd
->dom_server_addr
);
179 ysd
->dom_server_addr
.sin_family
= AF_INET
;
180 memcpy (&ysd
->dom_server_addr
.sin_port
,
181 ypbr
.ypbind_resp_u
.ypbind_bindinfo
.ypbind_binding_port
,
182 sizeof (ysd
->dom_server_addr
.sin_port
));
183 memcpy (&ysd
->dom_server_addr
.sin_addr
.s_addr
,
184 ypbr
.ypbind_resp_u
.ypbind_bindinfo
.ypbind_binding_addr
,
185 sizeof (ysd
->dom_server_addr
.sin_addr
.s_addr
));
186 strncpy (ysd
->dom_domain
, domain
, YPMAXDOMAIN
);
187 ysd
->dom_domain
[YPMAXDOMAIN
] = '\0';
189 ysd
->dom_socket
= RPC_ANYSOCK
;
190 ysd
->dom_client
= clntudp_create (&ysd
->dom_server_addr
, YPPROG
, YPVERS
,
191 UDPTIMEOUT
, &ysd
->dom_socket
);
193 if (ysd
->dom_client
!= NULL
)
194 /* If the program exits, close the socket */
195 if (fcntl (ysd
->dom_socket
, F_SETFD
, 1) == -1)
196 perror ("fcntl: F_SETFD");
199 if (ysd
->dom_client
== NULL
)
206 if (is_new
&& ypdb
!= NULL
)
208 ysd
->dom_pnext
= *ypdb
;
212 return YPERR_SUCCESS
;
216 __yp_unbind (dom_binding
*ydb
)
218 clnt_destroy (ydb
->dom_client
);
219 ydb
->dom_client
= NULL
;
223 yp_bind (const char *indomain
)
227 __libc_lock_lock (ypbindlist_lock
);
229 status
= __yp_bind (indomain
, &__ypbindlist
);
231 __libc_lock_unlock (ypbindlist_lock
);
237 yp_unbind_locked (const char *indomain
)
239 dom_binding
*ydbptr
, *ydbptr2
;
242 ydbptr
= __ypbindlist
;
244 while (ydbptr
!= NULL
)
246 if (strcmp (ydbptr
->dom_domain
, indomain
) == 0)
252 __ypbindlist
= __ypbindlist
->dom_pnext
;
254 ydbptr2
= ydbptr
->dom_pnext
;
260 ydbptr
= ydbptr
->dom_pnext
;
265 yp_unbind (const char *indomain
)
267 __libc_lock_lock (ypbindlist_lock
);
269 yp_unbind_locked (indomain
);
271 __libc_lock_unlock (ypbindlist_lock
);
277 do_ypcall (const char *domain
, u_long prog
, xdrproc_t xargs
,
278 caddr_t req
, xdrproc_t xres
, caddr_t resp
)
280 dom_binding
*ydb
= NULL
;
281 bool_t use_ypbindlist
= FALSE
;
283 enum clnt_stat result
;
284 int saved_errno
= errno
;
287 status
= YPERR_YPERR
;
289 __libc_lock_lock (ypbindlist_lock
);
290 if (__ypbindlist
!= NULL
)
295 if (strcmp (domain
, ydb
->dom_domain
) == 0)
297 ydb
= ydb
->dom_pnext
;
300 use_ypbindlist
= TRUE
;
302 __libc_lock_unlock (ypbindlist_lock
);
305 __libc_lock_unlock (ypbindlist_lock
);
307 while (try < MAXTRIES
&& status
!= YPERR_SUCCESS
)
309 if (__yp_bind (domain
, &ydb
) != 0)
312 __libc_lock_unlock (ypbindlist_lock
);
313 __set_errno (saved_errno
);
317 result
= clnt_call (ydb
->dom_client
, prog
,
318 xargs
, req
, xres
, resp
, RPCTIMEOUT
);
320 if (result
!= RPC_SUCCESS
)
322 /* Don't print the error message on the first try. It
323 could be that we use cached data which is now invalid. */
325 clnt_perror (ydb
->dom_client
, "do_ypcall: clnt_call");
329 /* We use ypbindlist, and the old cached data is
330 invalid. unbind now and create a new binding */
331 yp_unbind_locked (domain
);
332 __libc_lock_unlock (ypbindlist_lock
);
333 use_ypbindlist
= FALSE
;
345 status
= YPERR_SUCCESS
;
351 __libc_lock_unlock (ypbindlist_lock
);
352 use_ypbindlist
= FALSE
;
362 __set_errno (saved_errno
);
368 __libc_lock_define_initialized (static, domainname_lock
)
371 yp_get_default_domain (char **outdomain
)
373 int result
= YPERR_SUCCESS
;;
376 __libc_lock_lock (domainname_lock
);
378 if (__ypdomainname
[0] == '\0')
380 if (getdomainname (__ypdomainname
, NIS_MAXNAMELEN
))
381 result
= YPERR_NODOM
;
382 else if (strcmp (__ypdomainname
, "(none)") == 0)
384 /* If domainname is not set, some systems will return "(none)" */
385 __ypdomainname
[0] = '\0';
386 result
= YPERR_NODOM
;
389 *outdomain
= __ypdomainname
;
392 *outdomain
= __ypdomainname
;
394 __libc_lock_unlock (domainname_lock
);
400 __yp_check (char **domain
)
404 if (__ypdomainname
[0] == '\0')
405 if (yp_get_default_domain (&unused
))
409 *domain
= __ypdomainname
;
411 if (yp_bind (__ypdomainname
) == 0)
417 yp_match (const char *indomain
, const char *inmap
, const char *inkey
,
418 const int inkeylen
, char **outval
, int *outvallen
)
422 enum clnt_stat result
;
424 if (indomain
== NULL
|| indomain
[0] == '\0' ||
425 inmap
== NULL
|| inmap
[0] == '\0' ||
426 inkey
== NULL
|| inkey
[0] == '\0' || inkeylen
<= 0)
427 return YPERR_BADARGS
;
429 req
.domain
= (char *) indomain
;
430 req
.map
= (char *) inmap
;
431 req
.key
.keydat_val
= (char *) inkey
;
432 req
.key
.keydat_len
= inkeylen
;
436 memset (&resp
, '\0', sizeof (resp
));
438 result
= do_ypcall (indomain
, YPPROC_MATCH
, (xdrproc_t
) xdr_ypreq_key
,
439 (caddr_t
) & req
, (xdrproc_t
) xdr_ypresp_val
,
442 if (result
!= YPERR_SUCCESS
)
444 if (resp
.stat
!= YP_TRUE
)
445 return ypprot_err (resp
.stat
);
447 *outvallen
= resp
.val
.valdat_len
;
448 *outval
= malloc (*outvallen
+ 1);
449 memcpy (*outval
, resp
.val
.valdat_val
, *outvallen
);
450 (*outval
)[*outvallen
] = '\0';
452 xdr_free ((xdrproc_t
) xdr_ypresp_val
, (char *) &resp
);
454 return YPERR_SUCCESS
;
458 yp_first (const char *indomain
, const char *inmap
, char **outkey
,
459 int *outkeylen
, char **outval
, int *outvallen
)
463 enum clnt_stat result
;
465 if (indomain
== NULL
|| indomain
[0] == '\0' ||
466 inmap
== NULL
|| inmap
[0] == '\0')
467 return YPERR_BADARGS
;
469 req
.domain
= (char *) indomain
;
470 req
.map
= (char *) inmap
;
472 *outkey
= *outval
= NULL
;
473 *outkeylen
= *outvallen
= 0;
474 memset (&resp
, '\0', sizeof (resp
));
476 result
= do_ypcall (indomain
, YPPROC_FIRST
, (xdrproc_t
) xdr_ypreq_nokey
,
477 (caddr_t
) & req
, (xdrproc_t
) xdr_ypresp_key_val
,
480 if (result
!= RPC_SUCCESS
)
482 if (resp
.stat
!= YP_TRUE
)
483 return ypprot_err (resp
.stat
);
485 *outkeylen
= resp
.key
.keydat_len
;
486 *outkey
= malloc (*outkeylen
+ 1);
487 memcpy (*outkey
, resp
.key
.keydat_val
, *outkeylen
);
488 (*outkey
)[*outkeylen
] = '\0';
489 *outvallen
= resp
.val
.valdat_len
;
490 *outval
= malloc (*outvallen
+ 1);
491 memcpy (*outval
, resp
.val
.valdat_val
, *outvallen
);
492 (*outval
)[*outvallen
] = '\0';
494 xdr_free ((xdrproc_t
) xdr_ypresp_key_val
, (char *) &resp
);
496 return YPERR_SUCCESS
;
500 yp_next (const char *indomain
, const char *inmap
, const char *inkey
,
501 const int inkeylen
, char **outkey
, int *outkeylen
, char **outval
,
506 enum clnt_stat result
;
508 if (indomain
== NULL
|| indomain
[0] == '\0' ||
509 inmap
== NULL
|| inmap
[0] == '\0' ||
510 inkeylen
<= 0 || inkey
== NULL
|| inkey
[0] == '\0')
511 return YPERR_BADARGS
;
513 req
.domain
= (char *) indomain
;
514 req
.map
= (char *) inmap
;
515 req
.key
.keydat_val
= (char *) inkey
;
516 req
.key
.keydat_len
= inkeylen
;
518 *outkey
= *outval
= NULL
;
519 *outkeylen
= *outvallen
= 0;
520 memset (&resp
, '\0', sizeof (resp
));
522 result
= do_ypcall (indomain
, YPPROC_NEXT
, (xdrproc_t
) xdr_ypreq_key
,
523 (caddr_t
) & req
, (xdrproc_t
) xdr_ypresp_key_val
,
526 if (result
!= YPERR_SUCCESS
)
528 if (resp
.stat
!= YP_TRUE
)
529 return ypprot_err (resp
.stat
);
531 *outkeylen
= resp
.key
.keydat_len
;
532 *outkey
= malloc (*outkeylen
+ 1);
533 memcpy (*outkey
, resp
.key
.keydat_val
, *outkeylen
);
534 (*outkey
)[*outkeylen
] = '\0';
535 *outvallen
= resp
.val
.valdat_len
;
536 *outval
= malloc (*outvallen
+ 1);
537 memcpy (*outval
, resp
.val
.valdat_val
, *outvallen
);
538 (*outval
)[*outvallen
] = '\0';
540 xdr_free ((xdrproc_t
) xdr_ypresp_key_val
, (char *) &resp
);
542 return YPERR_SUCCESS
;
546 yp_master (const char *indomain
, const char *inmap
, char **outname
)
550 enum clnt_stat result
;
552 if (indomain
== NULL
|| indomain
[0] == '\0' ||
553 inmap
== NULL
|| inmap
[0] == '\0')
554 return YPERR_BADARGS
;
556 req
.domain
= (char *) indomain
;
557 req
.map
= (char *) inmap
;
559 memset (&resp
, '\0', sizeof (ypresp_master
));
561 result
= do_ypcall (indomain
, YPPROC_MASTER
, (xdrproc_t
) xdr_ypreq_nokey
,
562 (caddr_t
) & req
, (xdrproc_t
) xdr_ypresp_master
, (caddr_t
) & resp
);
564 if (result
!= YPERR_SUCCESS
)
566 if (resp
.stat
!= YP_TRUE
)
567 return ypprot_err (resp
.stat
);
569 *outname
= strdup (resp
.peer
);
570 xdr_free ((xdrproc_t
) xdr_ypresp_master
, (char *) &resp
);
572 return *outname
== NULL
? YPERR_YPERR
: YPERR_SUCCESS
;
576 yp_order (const char *indomain
, const char *inmap
, unsigned int *outorder
)
578 struct ypreq_nokey req
;
579 struct ypresp_order resp
;
580 enum clnt_stat result
;
582 if (indomain
== NULL
|| indomain
[0] == '\0' ||
583 inmap
== NULL
|| inmap
== '\0')
584 return YPERR_BADARGS
;
586 req
.domain
= (char *) indomain
;
587 req
.map
= (char *) inmap
;
589 memset (&resp
, '\0', sizeof (resp
));
591 result
= do_ypcall (indomain
, YPPROC_ORDER
, (xdrproc_t
) xdr_ypreq_nokey
,
592 (caddr_t
) & req
, (xdrproc_t
) xdr_ypresp_order
, (caddr_t
) & resp
);
594 if (result
!= YPERR_SUCCESS
)
596 if (resp
.stat
!= YP_TRUE
)
597 return ypprot_err (resp
.stat
);
599 *outorder
= resp
.ordernum
;
600 xdr_free ((xdrproc_t
) xdr_ypresp_order
, (char *) &resp
);
602 return YPERR_SUCCESS
;
605 static void *ypall_data
;
606 static int (*ypall_foreach
) (int status
, char *key
, int keylen
,
607 char *val
, int vallen
, char *data
);
610 __xdr_ypresp_all (XDR
*xdrs
, u_long
*objp
)
614 struct ypresp_all resp
;
616 memset (&resp
, '\0', sizeof (struct ypresp_all
));
617 if (!xdr_ypresp_all (xdrs
, &resp
))
619 xdr_free ((xdrproc_t
) xdr_ypresp_all
, (char *) &resp
);
625 xdr_free ((xdrproc_t
) xdr_ypresp_all
, (char *) &resp
);
630 switch (resp
.ypresp_all_u
.val
.stat
)
634 char key
[resp
.ypresp_all_u
.val
.key
.keydat_len
+ 1];
635 char val
[resp
.ypresp_all_u
.val
.val
.valdat_len
+ 1];
636 int keylen
= resp
.ypresp_all_u
.val
.key
.keydat_len
;
637 int vallen
= resp
.ypresp_all_u
.val
.val
.valdat_len
;
639 /* We are not allowed to modify the key and val data.
640 But we are allowed to add data behind the buffer,
641 if we don't modify the length. So add an extra NUL
642 character to avoid trouble with broken code. */
644 memcpy (key
, resp
.ypresp_all_u
.val
.key
.keydat_val
, keylen
);
646 memcpy (val
, resp
.ypresp_all_u
.val
.val
.valdat_val
, vallen
);
648 xdr_free ((xdrproc_t
) xdr_ypresp_all
, (char *) &resp
);
649 if ((*ypall_foreach
) (*objp
, key
, keylen
,
650 val
, vallen
, ypall_data
))
655 *objp
= resp
.ypresp_all_u
.val
.stat
;
656 xdr_free ((xdrproc_t
) xdr_ypresp_all
, (char *) &resp
);
657 /* Sun says we don't need to make this call, but must return
658 immediatly. Since Solaris makes this call, we will call
659 the callback function, too. */
660 (*ypall_foreach
) (*objp
, NULL
, 0, NULL
, 0, ypall_data
);
667 yp_all (const char *indomain
, const char *inmap
,
668 const struct ypall_callback
*incallback
)
670 struct ypreq_nokey req
;
671 dom_binding
*ydb
= NULL
;
673 enum clnt_stat result
;
674 struct sockaddr_in clnt_sin
;
676 unsigned long status
;
678 int saved_errno
= errno
;
680 if (indomain
== NULL
|| indomain
[0] == '\0' ||
681 inmap
== NULL
|| inmap
== '\0')
682 return YPERR_BADARGS
;
687 while (try < MAXTRIES
&& res
!= YPERR_SUCCESS
)
689 if (__yp_bind (indomain
, &ydb
) != 0)
691 __set_errno (saved_errno
);
695 /* YPPROC_ALL get its own TCP channel to ypserv. Therefore we
696 close the socket opened by the __yp_bind call. */
697 close (ydb
->dom_socket
);
698 clnt_sock
= RPC_ANYSOCK
;
699 clnt_sin
= ydb
->dom_server_addr
;
700 clnt_sin
.sin_port
= 0;
701 clnt
= clnttcp_create (&clnt_sin
, YPPROG
, YPVERS
, &clnt_sock
, 0, 0);
705 __set_errno (saved_errno
);
708 req
.domain
= (char *) indomain
;
709 req
.map
= (char *) inmap
;
711 ypall_foreach
= incallback
->foreach
;
712 ypall_data
= (void *) incallback
->data
;
714 result
= clnt_call (clnt
, YPPROC_ALL
, (xdrproc_t
) xdr_ypreq_nokey
,
715 (caddr_t
) &req
, (xdrproc_t
) __xdr_ypresp_all
,
716 (caddr_t
) &status
, RPCTIMEOUT
);
718 if (result
!= RPC_SUCCESS
)
720 clnt_perror (clnt
, "yp_all: clnt_call");
729 if (status
!= YP_NOMORE
)
731 __set_errno (saved_errno
);
732 return ypprot_err (status
);
737 __set_errno (saved_errno
);
743 yp_maplist (const char *indomain
, struct ypmaplist
**outmaplist
)
745 struct ypresp_maplist resp
;
746 enum clnt_stat result
;
748 if (indomain
== NULL
|| indomain
[0] == '\0')
749 return YPERR_BADARGS
;
751 memset (&resp
, '\0', sizeof (resp
));
753 result
= do_ypcall (indomain
, YPPROC_MAPLIST
, (xdrproc_t
) xdr_domainname
,
754 (caddr_t
) & indomain
, (xdrproc_t
) xdr_ypresp_maplist
, (caddr_t
) & resp
);
756 if (result
!= YPERR_SUCCESS
)
758 if (resp
.stat
!= YP_TRUE
)
759 return ypprot_err (resp
.stat
);
761 *outmaplist
= resp
.maps
;
762 /* We give the list not free, this will be done by ypserv
763 xdr_free((xdrproc_t)xdr_ypresp_maplist, (char *)&resp); */
765 return YPERR_SUCCESS
;
769 yperr_string (const int error
)
776 return _("Request arguments bad");
778 return _("RPC failure on NIS operation");
780 return _("Can't bind to server which serves this domain");
782 return _("No such map in server's domain");
784 return _("No such key in map");
786 return _("Internal NIS error");
788 return _("Local resource allocation failure");
790 return _("No more records in map database");
792 return _("Can't communicate with portmapper");
794 return _("Can't communicate with ypbind");
796 return _("Can't communicate with ypserv");
798 return _("Local domain name not set");
800 return _("NIS map database is bad");
802 return _("NIS client/server version mismatch - can't supply service");
804 return _("Permission denied");
806 return _("Database is busy");
808 return _("Unknown NIS error code");
812 ypprot_err (const int code
)
817 return YPERR_SUCCESS
;
835 return YPERR_BADARGS
;
843 ypbinderr_string (const int error
)
850 return _("Internal ypbind error");
851 case YPBIND_ERR_NOSERV
:
852 return _("Domain not bound");
853 case YPBIND_ERR_RESC
:
854 return _("System resource allocation failure");
856 return _("Unknown ypbind error");
864 yp_update (char *domain
, char *map
, unsigned ypop
,
865 char *key
, int keylen
, char *data
, int datalen
)
869 ypupdate_args update_args
;
870 ypdelete_args delete_args
;
873 xdrproc_t xdr_argument
;
877 struct sockaddr saddr
;
878 char servername
[MAXNETNAMELEN
+ 1];
881 if (!domain
|| !map
|| !key
|| (ypop
!= YPOP_DELETE
&& !data
))
882 return YPERR_BADARGS
;
884 args
.update_args
.mapname
= map
;
885 args
.update_args
.key
.yp_buf_len
= keylen
;
886 args
.update_args
.key
.yp_buf_val
= key
;
887 args
.update_args
.datum
.yp_buf_len
= datalen
;
888 args
.update_args
.datum
.yp_buf_val
= data
;
890 if ((r
= yp_master (domain
, map
, &master
)) != 0)
893 if (!host2netname (servername
, master
, domain
))
895 fputs (_("yp_update: cannot convert host to netname\n"), stderr
);
899 if ((clnt
= clnt_create (master
, YPU_PROG
, YPU_VERS
, "tcp")) == NULL
)
901 clnt_pcreateerror ("yp_update: clnt_create");
905 if (!clnt_control (clnt
, CLGET_SERVER_ADDR
, (char *) &saddr
))
907 fputs (_("yp_update: cannot get server address\n"), stderr
);
916 xdr_argument
= (xdrproc_t
) xdr_ypupdate_args
;
919 xdr_argument
= (xdrproc_t
) xdr_ypdelete_args
;
922 return YPERR_BADARGS
;
926 clnt
->cl_auth
= authdes_create (servername
, WINDOW
, &saddr
, NULL
);
928 if (clnt
->cl_auth
== NULL
)
929 clnt
->cl_auth
= authunix_create_default ();
932 r
= clnt_call (clnt
, ypop
, xdr_argument
, (caddr_t
) &args
,
933 (xdrproc_t
) xdr_u_int
, (caddr_t
) &res
, RPCTIMEOUT
);
935 if (r
== RPC_AUTHERROR
)
937 if (clnt
->cl_auth
->ah_cred
.oa_flavor
== AUTH_DES
)
939 clnt
->cl_auth
= authunix_create_default ();
945 if (r
!= RPC_SUCCESS
)
947 clnt_perror (clnt
, "yp_update: clnt_call");