basic definitions for ARM standalone.
[glibc/history.git] / nis / ypclnt.c
blob85597144b22aa59dcdb941114b3c411b783156bb
1 /* Copyright (C) 1996, 1997 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 <bits/libc-lock.h>
24 #include <rpc/rpc.h>
25 #include <rpcsvc/nis.h>
26 #include <rpcsvc/yp.h>
27 #include <rpcsvc/ypclnt.h>
28 #include <rpcsvc/ypupd.h>
30 struct dom_binding
32 struct dom_binding *dom_pnext;
33 char dom_domain[YPMAXDOMAIN + 1];
34 struct sockaddr_in dom_server_addr;
35 int dom_socket;
36 CLIENT *dom_client;
37 long int dom_vers;
39 typedef struct dom_binding dom_binding;
41 static struct timeval TIMEOUT = {25, 0};
42 static int const MAXTRIES = 5;
43 static char __ypdomainname[NIS_MAXNAMELEN + 1] = "\0";
44 __libc_lock_define_initialized (static, ypbindlist_lock)
45 static dom_binding *__ypbindlist = NULL;
48 static int
49 __yp_bind (const char *domain, dom_binding ** ypdb)
51 struct sockaddr_in clnt_saddr;
52 struct ypbind_resp ypbr;
53 dom_binding *ysd;
54 int clnt_sock;
55 CLIENT *client;
56 int is_new = 0;
57 int try;
59 if (ypdb != NULL)
60 *ypdb = NULL;
62 if ((domain == NULL) || (strlen (domain) == 0))
63 return YPERR_BADARGS;
65 ysd = __ypbindlist;
66 while (ysd != NULL)
68 if (strcmp (domain, ysd->dom_domain) == 0)
69 break;
70 ysd = ysd->dom_pnext;
73 if (ysd == NULL)
75 is_new = 1;
76 ysd = (dom_binding *) malloc (sizeof *ysd);
77 memset (ysd, '\0', sizeof *ysd);
78 ysd->dom_socket = -1;
79 ysd->dom_vers = -1;
82 try = 0;
86 try++;
87 if (try > MAXTRIES)
89 if (is_new)
90 free (ysd);
91 return YPERR_YPBIND;
94 if (ysd->dom_vers == -1)
96 if(ysd->dom_client)
98 clnt_destroy(ysd->dom_client);
99 ysd->dom_client = NULL;
100 ysd->dom_socket = -1;
102 memset (&clnt_saddr, '\0', sizeof clnt_saddr);
103 clnt_saddr.sin_family = AF_INET;
104 clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
105 clnt_sock = RPC_ANYSOCK;
106 client = clnttcp_create (&clnt_saddr, YPBINDPROG, YPBINDVERS,
107 &clnt_sock, 0, 0);
108 if (client == NULL)
110 if (is_new)
111 free (ysd);
112 return YPERR_YPBIND;
115 ** Check the port number -- should be < IPPORT_RESERVED.
116 ** If not, it's possible someone has registered a bogus
117 ** ypbind with the portmapper and is trying to trick us.
119 if (ntohs(clnt_saddr.sin_port) >= IPPORT_RESERVED)
121 clnt_destroy(client);
122 if (is_new)
123 free(ysd);
124 return(YPERR_YPBIND);
127 if (clnt_call (client, YPBINDPROC_DOMAIN,
128 (xdrproc_t) xdr_domainname, (caddr_t) &domain,
129 (xdrproc_t) xdr_ypbind_resp,
130 (caddr_t) &ypbr, TIMEOUT) != RPC_SUCCESS)
132 clnt_destroy (client);
133 if (is_new)
134 free (ysd);
135 return YPERR_YPBIND;
138 clnt_destroy (client);
139 if (ypbr.ypbind_status != YPBIND_SUCC_VAL)
141 switch (ypbr.ypbind_resp_u.ypbind_error)
143 case YPBIND_ERR_ERR:
144 fputs (_("YPBINDPROC_DOMAIN: Internal error\n"), stderr);
145 break;
146 case YPBIND_ERR_NOSERV:
147 fprintf (stderr,
148 _("YPBINDPROC_DOMAIN: No server for domain %s\n"),
149 domain);
150 break;
151 case YPBIND_ERR_RESC:
152 fputs (_("YPBINDPROC_DOMAIN: Resource allocation failure\n"),
153 stderr);
154 break;
155 default:
156 fputs (_("YPBINDPROC_DOMAIN: Unknown error\n"), stderr);
157 break;
159 if (is_new)
160 free (ysd);
161 return YPERR_DOMAIN;
163 memset (&ysd->dom_server_addr, '\0', sizeof ysd->dom_server_addr);
164 ysd->dom_server_addr.sin_family = AF_INET;
165 memcpy (&ysd->dom_server_addr.sin_port,
166 ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port,
167 sizeof (ysd->dom_server_addr.sin_port));
168 memcpy (&ysd->dom_server_addr.sin_addr.s_addr,
169 ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
170 sizeof (ysd->dom_server_addr.sin_addr.s_addr));
171 ysd->dom_vers = YPVERS;
172 strncpy (ysd->dom_domain, domain, YPMAXDOMAIN);
173 ysd->dom_domain[YPMAXDOMAIN] = '\0';
176 if (ysd->dom_client)
177 clnt_destroy (ysd->dom_client);
178 ysd->dom_socket = RPC_ANYSOCK;
179 ysd->dom_client = clntudp_create (&ysd->dom_server_addr, YPPROG, YPVERS,
180 TIMEOUT, &ysd->dom_socket);
181 if (ysd->dom_client == NULL)
182 ysd->dom_vers = -1;
185 while (ysd->dom_client == NULL);
187 /* If the program exists, close the socket */
188 if (fcntl (ysd->dom_socket, F_SETFD, 1) == -1)
189 perror (_("fcntl: F_SETFD"));
191 if (is_new)
193 ysd->dom_pnext = __ypbindlist;
194 __ypbindlist = ysd;
197 if (NULL != ypdb)
198 *ypdb = ysd;
200 return YPERR_SUCCESS;
203 static void
204 __yp_unbind (dom_binding *ydb)
206 clnt_destroy (ydb->dom_client);
207 ydb->dom_client = NULL;
208 ydb->dom_socket = -1;
211 static int
212 do_ypcall (const char *domain, u_long prog, xdrproc_t xargs,
213 caddr_t req, xdrproc_t xres, caddr_t resp)
215 dom_binding *ydb = NULL;
216 int try, result;
218 try = 0;
219 result = YPERR_YPERR;
221 while (try < MAXTRIES && result != RPC_SUCCESS)
223 __libc_lock_lock (ypbindlist_lock);
225 if (__yp_bind (domain, &ydb) != 0)
227 __libc_lock_unlock (ypbindlist_lock);
228 return YPERR_DOMAIN;
231 result = clnt_call (ydb->dom_client, prog,
232 xargs, req, xres, resp, TIMEOUT);
234 if (result != RPC_SUCCESS)
236 clnt_perror (ydb->dom_client, "do_ypcall: clnt_call");
237 ydb->dom_vers = -1;
238 __yp_unbind (ydb);
239 result = YPERR_RPC;
242 __libc_lock_unlock (ypbindlist_lock);
244 try++;
247 return result;
251 yp_bind (const char *indomain)
253 int status;
255 __libc_lock_lock (ypbindlist_lock);
257 status = __yp_bind (indomain, NULL);
259 __libc_lock_unlock (ypbindlist_lock);
261 return status;
264 void
265 yp_unbind (const char *indomain)
267 dom_binding *ydbptr, *ydbptr2;
269 __libc_lock_lock (ypbindlist_lock);
271 ydbptr2 = NULL;
272 ydbptr = __ypbindlist;
273 while (ydbptr != NULL)
275 if (strcmp (ydbptr->dom_domain, indomain) == 0)
277 dom_binding *work;
279 work = ydbptr;
280 if (ydbptr2 == NULL)
281 __ypbindlist = __ypbindlist->dom_pnext;
282 else
283 ydbptr2 = ydbptr->dom_pnext;
284 __yp_unbind (work);
285 free (work);
286 break;
288 ydbptr2 = ydbptr;
289 ydbptr = ydbptr->dom_pnext;
292 __libc_lock_unlock (ypbindlist_lock);
294 return;
297 __libc_lock_define_initialized (static, domainname_lock)
300 yp_get_default_domain (char **outdomain)
302 int result = YPERR_SUCCESS;;
303 *outdomain = NULL;
305 __libc_lock_lock (domainname_lock);
307 if (__ypdomainname[0] == '\0')
309 if (getdomainname (__ypdomainname, NIS_MAXNAMELEN))
310 result = YPERR_NODOM;
311 else
312 *outdomain = __ypdomainname;
314 else
315 *outdomain = __ypdomainname;
317 __libc_lock_unlock (domainname_lock);
319 return result;
323 __yp_check (char **domain)
325 char *unused;
327 if (__ypdomainname[0] == '\0')
328 if (yp_get_default_domain (&unused))
329 return 0;
330 else if (strcmp (__ypdomainname, "(none)") == 0)
331 return 0;
333 if (domain)
334 *domain = __ypdomainname;
336 if (yp_bind (__ypdomainname) == 0)
337 return 1;
338 return 0;
342 yp_match (const char *indomain, const char *inmap, const char *inkey,
343 const int inkeylen, char **outval, int *outvallen)
345 ypreq_key req;
346 ypresp_val resp;
347 int result;
349 if (indomain == NULL || indomain[0] == '\0' ||
350 inmap == NULL || inmap[0] == '\0' ||
351 inkey == NULL || inkey[0] == '\0' || inkeylen <= 0)
352 return YPERR_BADARGS;
354 req.domain = (char *) indomain;
355 req.map = (char *) inmap;
356 req.key.keydat_val = (char *) inkey;
357 req.key.keydat_len = inkeylen;
359 *outval = NULL;
360 *outvallen = 0;
361 memset (&resp, '\0', sizeof (resp));
363 result = do_ypcall (indomain, YPPROC_MATCH, (xdrproc_t) xdr_ypreq_key,
364 (caddr_t) & req, (xdrproc_t) xdr_ypresp_val,
365 (caddr_t) & resp);
367 if (result != RPC_SUCCESS)
368 return result;
369 if (resp.stat != YP_TRUE)
370 return ypprot_err (resp.stat);
372 *outvallen = resp.val.valdat_len;
373 *outval = malloc (*outvallen + 1);
374 memcpy (*outval, resp.val.valdat_val, *outvallen);
375 (*outval)[*outvallen] = '\0';
377 xdr_free ((xdrproc_t) xdr_ypresp_val, (char *) &resp);
379 return YPERR_SUCCESS;
383 yp_first (const char *indomain, const char *inmap, char **outkey,
384 int *outkeylen, char **outval, int *outvallen)
386 ypreq_nokey req;
387 ypresp_key_val resp;
388 int result;
390 if (indomain == NULL || indomain[0] == '\0' ||
391 inmap == NULL || inmap[0] == '\0')
392 return YPERR_BADARGS;
394 req.domain = (char *) indomain;
395 req.map = (char *) inmap;
397 *outkey = *outval = NULL;
398 *outkeylen = *outvallen = 0;
399 memset (&resp, '\0', sizeof (resp));
401 result = do_ypcall (indomain, YPPROC_FIRST, (xdrproc_t) xdr_ypreq_nokey,
402 (caddr_t) & req, (xdrproc_t) xdr_ypresp_key_val,
403 (caddr_t) & resp);
405 if (result != RPC_SUCCESS)
406 return result;
407 if (resp.stat != YP_TRUE)
408 return ypprot_err (resp.stat);
410 *outkeylen = resp.key.keydat_len;
411 *outkey = malloc (*outkeylen + 1);
412 memcpy (*outkey, resp.key.keydat_val, *outkeylen);
413 (*outkey)[*outkeylen] = '\0';
414 *outvallen = resp.val.valdat_len;
415 *outval = malloc (*outvallen + 1);
416 memcpy (*outval, resp.val.valdat_val, *outvallen);
417 (*outval)[*outvallen] = '\0';
419 xdr_free ((xdrproc_t) xdr_ypresp_key_val, (char *) &resp);
421 return YPERR_SUCCESS;
425 yp_next (const char *indomain, const char *inmap, const char *inkey,
426 const int inkeylen, char **outkey, int *outkeylen, char **outval,
427 int *outvallen)
429 ypreq_key req;
430 ypresp_key_val resp;
431 int result;
433 if (indomain == NULL || indomain[0] == '\0' ||
434 inmap == NULL || inmap[0] == '\0' ||
435 inkeylen <= 0 || inkey == NULL || inkey[0] == '\0')
436 return YPERR_BADARGS;
438 req.domain = (char *) indomain;
439 req.map = (char *) inmap;
440 req.key.keydat_val = (char *) inkey;
441 req.key.keydat_len = inkeylen;
443 *outkey = *outval = NULL;
444 *outkeylen = *outvallen = 0;
445 memset (&resp, '\0', sizeof (resp));
447 result = do_ypcall (indomain, YPPROC_NEXT, (xdrproc_t) xdr_ypreq_key,
448 (caddr_t) & req, (xdrproc_t) xdr_ypresp_key_val,
449 (caddr_t) & resp);
451 if (result != RPC_SUCCESS)
452 return result;
453 if (resp.stat != YP_TRUE)
454 return ypprot_err (resp.stat);
456 *outkeylen = resp.key.keydat_len;
457 *outkey = malloc (*outkeylen + 1);
458 memcpy (*outkey, resp.key.keydat_val, *outkeylen);
459 (*outkey)[*outkeylen] = '\0';
460 *outvallen = resp.val.valdat_len;
461 *outval = malloc (*outvallen + 1);
462 memcpy (*outval, resp.val.valdat_val, *outvallen);
463 (*outval)[*outvallen] = '\0';
465 xdr_free ((xdrproc_t) xdr_ypresp_key_val, (char *) &resp);
467 return YPERR_SUCCESS;
471 yp_master (const char *indomain, const char *inmap, char **outname)
473 ypreq_nokey req;
474 ypresp_master resp;
475 int result;
477 if (indomain == NULL || indomain[0] == '\0' ||
478 inmap == NULL || inmap[0] == '\0')
479 return YPERR_BADARGS;
481 req.domain = (char *) indomain;
482 req.map = (char *) inmap;
484 memset (&resp, '\0', sizeof (ypresp_master));
486 result = do_ypcall (indomain, YPPROC_MASTER, (xdrproc_t) xdr_ypreq_nokey,
487 (caddr_t) & req, (xdrproc_t) xdr_ypresp_master, (caddr_t) & resp);
489 if (result != RPC_SUCCESS)
490 return result;
491 if (resp.stat != YP_TRUE)
492 return ypprot_err (resp.stat);
494 *outname = strdup (resp.peer);
495 xdr_free ((xdrproc_t) xdr_ypresp_master, (char *) &resp);
497 return YPERR_SUCCESS;
501 yp_order (const char *indomain, const char *inmap, unsigned int *outorder)
503 struct ypreq_nokey req;
504 struct ypresp_order resp;
505 int result;
507 if (indomain == NULL || indomain[0] == '\0' ||
508 inmap == NULL || inmap == '\0')
509 return YPERR_BADARGS;
511 req.domain = (char *) indomain;
512 req.map = (char *) inmap;
514 memset (&resp, '\0', sizeof (resp));
516 result = do_ypcall (indomain, YPPROC_ORDER, (xdrproc_t) xdr_ypreq_nokey,
517 (caddr_t) & req, (xdrproc_t) xdr_ypresp_order, (caddr_t) & resp);
519 if (result != RPC_SUCCESS)
520 return result;
521 if (resp.stat != YP_TRUE)
522 return ypprot_err (resp.stat);
524 *outorder = resp.ordernum;
525 xdr_free ((xdrproc_t) xdr_ypresp_order, (char *) &resp);
527 return YPERR_SUCCESS;
530 static void *ypall_data;
531 static int (*ypall_foreach) __P ((int status, char *key, int keylen,
532 char *val, int vallen, char *data));
534 static bool_t
535 __xdr_ypresp_all (XDR * xdrs, u_long * objp)
537 while (1)
539 struct ypresp_all resp;
541 memset (&resp, '\0', sizeof (struct ypresp_all));
542 if (!xdr_ypresp_all (xdrs, &resp))
544 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
545 *objp = YP_YPERR;
546 return (FALSE);
548 if (resp.more == 0)
550 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
551 *objp = YP_NOMORE;
552 return (FALSE);
555 switch (resp.ypresp_all_u.val.stat)
557 case YP_TRUE:
559 char key[resp.ypresp_all_u.val.key.keydat_len + 1];
560 char val[resp.ypresp_all_u.val.val.valdat_len + 1];
561 int keylen = resp.ypresp_all_u.val.key.keydat_len;
562 int vallen = resp.ypresp_all_u.val.val.valdat_len;
564 *objp = YP_TRUE;
565 memcpy (key, resp.ypresp_all_u.val.key.keydat_val, keylen);
566 key[keylen] = '\0';
567 memcpy (val, resp.ypresp_all_u.val.val.valdat_val, vallen);
568 val[vallen] = '\0';
569 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
570 if ((*ypall_foreach) (*objp, key, keylen,
571 val, vallen, ypall_data))
572 return TRUE;
574 break;
575 case YP_NOMORE:
576 *objp = YP_NOMORE;
577 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
578 return TRUE;
579 break;
580 default:
581 *objp = resp.ypresp_all_u.val.stat;
582 xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
583 return TRUE;
589 yp_all (const char *indomain, const char *inmap,
590 const struct ypall_callback *incallback)
592 struct ypreq_nokey req;
593 dom_binding *ydb;
594 int try, result;
595 struct sockaddr_in clnt_sin;
596 CLIENT *clnt;
597 unsigned long status;
598 int clnt_sock;
600 if (indomain == NULL || indomain[0] == '\0' ||
601 inmap == NULL || inmap == '\0')
602 return YPERR_BADARGS;
604 try = 0;
605 result = YPERR_YPERR;
607 while (try < MAXTRIES && result != RPC_SUCCESS)
609 __libc_lock_lock (ypbindlist_lock);
611 if (__yp_bind (indomain, &ydb) != 0)
613 __libc_lock_unlock (ypbindlist_lock);
614 return YPERR_DOMAIN;
617 /* YPPROC_ALL get its own TCP channel to ypserv */
618 clnt_sock = RPC_ANYSOCK;
619 clnt_sin = ydb->dom_server_addr;
620 clnt_sin.sin_port = 0;
621 clnt = clnttcp_create (&clnt_sin, YPPROG, YPVERS, &clnt_sock, 0, 0);
622 if (clnt == NULL)
624 puts ("yp_all: clnttcp_create failed");
625 __libc_lock_unlock (ypbindlist_lock);
626 return YPERR_PMAP;
628 req.domain = (char *) indomain;
629 req.map = (char *) inmap;
631 ypall_foreach = incallback->foreach;
632 ypall_data = (void *) incallback->data;
634 result = clnt_call (clnt, YPPROC_ALL, (xdrproc_t) xdr_ypreq_nokey,
635 (caddr_t) &req, (xdrproc_t) __xdr_ypresp_all,
636 (caddr_t) &status, TIMEOUT);
638 if (result != RPC_SUCCESS)
640 clnt_perror (ydb->dom_client, "yp_all: clnt_call");
641 clnt_destroy (clnt);
642 __yp_unbind (ydb);
643 result = YPERR_RPC;
645 else
647 clnt_destroy (clnt);
648 result = YPERR_SUCCESS;
651 __libc_lock_unlock (ypbindlist_lock);
653 if (status != YP_NOMORE)
654 return ypprot_err (status);
655 try++;
658 return result;
662 yp_maplist (const char *indomain, struct ypmaplist **outmaplist)
664 struct ypresp_maplist resp;
665 int result;
667 if (indomain == NULL || indomain[0] == '\0')
668 return YPERR_BADARGS;
670 memset (&resp, '\0', sizeof (resp));
672 result = do_ypcall (indomain, YPPROC_MAPLIST, (xdrproc_t) xdr_domainname,
673 (caddr_t) & indomain, (xdrproc_t) xdr_ypresp_maplist, (caddr_t) & resp);
675 if (result != RPC_SUCCESS)
676 return result;
677 if (resp.stat != YP_TRUE)
678 return ypprot_err (resp.stat);
680 *outmaplist = resp.maps;
681 /* We give the list not free, this will be done by ypserv
682 xdr_free((xdrproc_t)xdr_ypresp_maplist, (char *)&resp); */
684 return YPERR_SUCCESS;
687 const char *
688 yperr_string (const int error)
690 switch (error)
692 case YPERR_SUCCESS:
693 return _("Success");
694 case YPERR_BADARGS:
695 return _("Request arguments bad");
696 case YPERR_RPC:
697 return _("RPC failure on NIS operation");
698 case YPERR_DOMAIN:
699 return _("Can't bind to server which serves this domain");
700 case YPERR_MAP:
701 return _("No such map in server's domain");
702 case YPERR_KEY:
703 return _("No such key in map");
704 case YPERR_YPERR:
705 return _("Internal NIS error");
706 case YPERR_RESRC:
707 return _("Local resource allocation failure");
708 case YPERR_NOMORE:
709 return _("No more records in map database");
710 case YPERR_PMAP:
711 return _("Can't communicate with portmapper");
712 case YPERR_YPBIND:
713 return _("Can't communicate with ypbind");
714 case YPERR_YPSERV:
715 return _("Can't communicate with ypserv");
716 case YPERR_NODOM:
717 return _("Local domain name not set");
718 case YPERR_BADDB:
719 return _("NIS map data base is bad");
720 case YPERR_VERS:
721 return _("NIS client/server version mismatch - can't supply service");
722 case YPERR_ACCESS:
723 return _("Permission denied");
724 case YPERR_BUSY:
725 return _("Database is busy");
727 return _("Unknown NIS error code");
731 ypprot_err (const int code)
733 switch (code)
735 case YP_TRUE:
736 return YPERR_SUCCESS;
737 case YP_NOMORE:
738 return YPERR_NOMORE;
739 case YP_FALSE:
740 return YPERR_YPERR;
741 case YP_NOMAP:
742 return YPERR_MAP;
743 case YP_NODOM:
744 return YPERR_DOMAIN;
745 case YP_NOKEY:
746 return YPERR_KEY;
747 case YP_BADOP:
748 return YPERR_YPERR;
749 case YP_BADDB:
750 return YPERR_BADDB;
751 case YP_YPERR:
752 return YPERR_YPERR;
753 case YP_BADARGS:
754 return YPERR_BADARGS;
755 case YP_VERS:
756 return YPERR_VERS;
758 return YPERR_YPERR;
761 const char *
762 ypbinderr_string (const int error)
764 switch (error)
766 case 0:
767 return _("Success");
768 case YPBIND_ERR_ERR:
769 return _("Internal ypbind error");
770 case YPBIND_ERR_NOSERV:
771 return _("Domain not bound");
772 case YPBIND_ERR_RESC:
773 return _("System resource allocation failure");
774 default:
775 return _("Unknown ypbind error");
780 #define WINDOW 60
783 yp_update (char *domain, char *map, unsigned ypop,
784 char *key, int keylen, char *data, int datalen)
786 #if defined (HAVE_SECURE_RPC)
787 union
789 ypupdate_args update_args;
790 ypdelete_args delete_args;
792 args;
793 xdrproc_t xdr_argument;
794 unsigned res = 0;
795 CLIENT *clnt;
796 char *master;
797 struct sockaddr saddr;
798 char servername[MAXNETNAMELEN + 1];
799 int r;
801 if (!domain || !map || !key || (ypop != YPOP_DELETE && !data))
802 return YPERR_BADARGS;
804 args.update_args.mapname = map;
805 args.update_args.key.yp_buf_len = keylen;
806 args.update_args.key.yp_buf_val = key;
807 args.update_args.datum.yp_buf_len = datalen;
808 args.update_args.datum.yp_buf_val = data;
810 if ((r = yp_master (domain, map, &master)) != 0)
811 return r;
813 if (!host2netname (servername, master, domain))
815 fputs (_("yp_update: cannot convert host to netname\n"), stderr);
816 return YPERR_YPERR;
819 if ((clnt = clnt_create (master, YPU_PROG, YPU_VERS, "tcp")) == NULL)
821 clnt_pcreateerror ("yp_update: clnt_create");
822 return YPERR_RPC;
825 if (!clnt_control (clnt, CLGET_SERVER_ADDR, (char *) &saddr))
827 fputs (_("yp_update: cannot get server address\n"), stderr);
828 return YPERR_RPC;
831 switch (ypop)
833 case YPOP_CHANGE:
834 case YPOP_INSERT:
835 case YPOP_STORE:
836 xdr_argument = (xdrproc_t) xdr_ypupdate_args;
837 break;
838 case YPOP_DELETE:
839 xdr_argument = (xdrproc_t) xdr_ypdelete_args;
840 break;
841 default:
842 return YPERR_BADARGS;
843 break;
846 clnt->cl_auth = authdes_create (servername, WINDOW, &saddr, NULL);
848 if (clnt->cl_auth == NULL)
849 clnt->cl_auth = authunix_create_default ();
851 again:
852 r = clnt_call (clnt, ypop, xdr_argument, (caddr_t) &args,
853 (xdrproc_t) xdr_u_int, (caddr_t) &res, TIMEOUT);
855 if (r == RPC_AUTHERROR)
857 if (clnt->cl_auth->ah_cred.oa_flavor == AUTH_DES)
859 clnt->cl_auth = authunix_create_default ();
860 goto again;
862 else
863 return YPERR_ACCESS;
865 if (r != RPC_SUCCESS)
867 clnt_perror (clnt, "yp_update: clnt_call");
868 return YPERR_RPC;
870 return res;
871 #else
872 return YPERR_YPERR;
873 #endif