4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
21 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
22 * Use is subject to license terms.
24 * Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T
27 * Portions of this source code were derived from Berkeley
28 * 4.3 BSD under license from the Regents of the University of
32 * Copyright (c) 2016 by Delphix. All rights reserved.
34 #pragma ident "%Z%%M% %I% %E% SMI"
38 extern int gettimeofday(struct timeval
*);
40 #include <sys/types.h>
49 #include <sys/types.h>
55 #include <rpc/nettype.h>
56 #include <rpc/rpcb_prot.h>
57 #include <rpc/rpcb_clnt.h>
58 #include <sys/systeminfo.h>
59 #include <sys/select.h>
69 #define YPPROG ((ulong_t)109999)
71 #define YPBINDPROG ((ulong_t)109998)
74 #define INTER_TRY 12 /* Seconds between tries */
75 #define PORTMAP_TIME 30 /* Seconds before decide its down */
76 #define TIMEOUT INTER_TRY*4 /* Total time for timeout */
77 #define CUR_PAR 4 /* Total parallal yppushes */
78 #define MIN_GRACE 25 /* select timeout and minimum grace */
79 #define GRACE_PERIOD 800 /* Total seconds we'll wait for */
80 /* responses from ypxfrs, yes */
81 /* virginia yp map transfers */
82 /* can take a long time, we */
83 /* only worry if the slave */
88 static char *domain
= NULL
;
89 static char *host
= NULL
;
90 static char my_name
[YPMAXPEER
+1];
91 static char default_domain_name
[YPMAXDOMAIN
];
92 static char domain_alias
[MAXNAMLEN
]; /* nickname for domain - */
93 /* used in sysv filesystems */
94 static char map_alias
[MAXNAMLEN
]; /* nickname for map - */
95 /* used in sysv filesystems */
96 static char *map
= NULL
;
97 static bool verbose
= FALSE
;
98 static bool onehost
= FALSE
;
99 static bool oldxfr
= FALSE
;
100 static bool callback_timeout
= FALSE
; /* set when a callback times out */
101 int grace_period
= GRACE_PERIOD
;
102 int curpar
= CUR_PAR
; /* should be set by other stuff */
103 static char ypmapname
[1024]; /* Used to check for map's existence */
105 static struct timeval intertry
= {
106 INTER_TRY
, /* Seconds */
109 static struct timeval timeout
= {
110 TIMEOUT
, /* Seconds */
113 static SVCXPRT
*transport4
;
114 static SVCXPRT
*transport6
;
116 struct server
*pnext
;
117 struct dom_binding domb
;
118 char svc_name
[YPMAXPEER
+1];
119 unsigned long xactid
;
120 unsigned short state
;
121 unsigned long status
;
125 #define n_conf dom_binding->ypbind_nconf
126 #define svc_addr dom_binding->ypbind_svcaddr
127 static struct server
*server_list
= (struct server
*)NULL
;
128 static struct server
*active_list
= (struct server
*)NULL
;
130 /* State values for server.state field */
133 #define SSTAT_CALLED 1
134 #define SSTAT_RESPONDED 2
135 #define SSTAT_PROGNOTREG 3
137 #define SSTAT_RSCRC 5
138 #define SSTAT_SYSTEM 6
140 static char err_usage
[] =
141 "Usage:\n\typpush [-p <par>] [-d <domainname>] [-h <hostname>] [-v] map\n";
142 static char err_bad_args
[] =
143 "The %s argument is bad.\n";
144 static char err_cant_get_kname
[] =
145 "Can't get %s from system call.\n";
146 static char err_null_kname
[] =
147 "The %s hasn't been set on this machine.\n";
148 static char err_bad_domainname
[] = "domainname";
149 static char err_cant_bind
[] =
150 "Can't find a yp server for domain %s. Reason: %s.\n";
151 static char err_cant_build_serverlist
[] =
152 "Can't build server list from map \"ypservers\". Reason: %s.\n";
153 static char err_cant_find_host
[] =
154 "Can't find host %s in map \"ypservers\".\n";
156 * State_duple table. All messages should take 1 arg - the node name.
162 static struct state_duple state_duples
[] = {
163 {SSTAT_INIT
, "Internal error trying to talk to %s."},
164 {SSTAT_CALLED
, "%s has been called."},
165 {SSTAT_RESPONDED
, "%s (v1 ypserv) sent an old-style request."},
166 {SSTAT_PROGNOTREG
, "nis server not registered at %s."},
167 {SSTAT_RPC
, "RPC error to %s: "},
168 {SSTAT_RSCRC
, "Local resource allocation failure - can't talk to %s."},
169 {SSTAT_SYSTEM
, "System error talking to %s: "},
173 * Status_duple table. No messages should require any args.
175 struct status_duple
{
179 static struct status_duple status_duples
[] = {
180 {YPPUSH_SUCC
, "Map successfully transferred."},
182 "Transfer not done: master's version isn't newer."},
183 {YPPUSH_NOMAP
, "Failed - ypxfr there can't find a server for map."},
184 {YPPUSH_NODOM
, "Failed - domain isn't supported."},
185 {YPPUSH_RSRC
, "Failed - local resource allocation failure."},
186 {YPPUSH_RPC
, "Failed - ypxfr had an RPC failure"},
187 {YPPUSH_MADDR
, "Failed - ypxfr couldn't get the map master's address."},
188 {YPPUSH_YPERR
, "Failed - nis server or map format error."},
189 {YPPUSH_BADARGS
, "Failed - args to ypxfr were bad."},
190 {YPPUSH_DBM
, "Failed - dbm operation on map failed."},
191 {YPPUSH_FILE
, "Failed - file I/O operation on map failed"},
192 {YPPUSH_SKEW
, "Failed - map version skew during transfer."},
194 "Map successfully transferred, but ypxfr \
195 couldn't send \"Clear map\" to ypserv "},
197 "Failed - no local order number in map - use -f flag to ypxfr."},
198 {YPPUSH_XFRERR
, "Failed - ypxfr internal error."},
199 {YPPUSH_REFUSED
, "Failed - Transfer request refused."},
201 "Failed - System V domain/map alias not in alias file."},
207 struct rpcerr_duple
{
208 enum clnt_stat rpc_stat
;
211 static struct rpcerr_duple rpcerr_duples
[] = {
212 {RPC_SUCCESS
, "RPC success"},
213 {RPC_CANTENCODEARGS
, "RPC Can't encode args"},
214 {RPC_CANTDECODERES
, "RPC Can't decode results"},
215 {RPC_CANTSEND
, "RPC Can't send"},
216 {RPC_CANTRECV
, "RPC Can't recv"},
217 {RPC_TIMEDOUT
, "NIS server registered, but does not respond"},
218 {RPC_VERSMISMATCH
, "RPC version mismatch"},
219 {RPC_AUTHERROR
, "RPC auth error"},
220 {RPC_PROGUNAVAIL
, "RPC remote program unavailable"},
221 {RPC_PROGVERSMISMATCH
, "RPC program mismatch"},
222 {RPC_PROCUNAVAIL
, "RPC unknown procedure"},
223 {RPC_CANTDECODEARGS
, "RPC Can't decode args"},
224 {RPC_UNKNOWNHOST
, "unknown host"},
225 {RPC_RPCBFAILURE
, "rpcbind failure (host is down?)"},
226 {RPC_PROGNOTREGISTERED
, "RPC prog not registered"},
227 {RPC_SYSTEMERROR
, "RPC system error"},
228 {RPC_SUCCESS
, (char *)NULL
} /* Duplicate rpc_stat */
229 /* unused in list-end */
233 static void get_default_domain_name(void);
234 static void get_command_line_args(int argc
, char **argv
);
235 static unsigned short send_message(struct server
*ps
,
236 unsigned long program
, long *err
);
237 static void make_server_list(void);
238 static void one_host_list(void);
239 static void add_server(char *sname
, int namelen
);
240 static int generate_callback(unsigned long *program
);
241 static void xactid_seed(unsigned long *xactid
);
242 static void main_loop(unsigned long program
);
243 static void listener_exit(unsigned long program
, int stat
);
244 static void listener_dispatch(struct svc_req
*rqstp
, SVCXPRT
*transp
);
245 static void print_state_msg(struct server
*s
, long e
);
246 static void print_callback_msg(struct server
*s
);
247 static void rpcerr_msg(enum clnt_stat e
);
248 static void get_xfr_response(SVCXPRT
*transp
);
251 extern void sysvconfig(void);
253 extern int yp_getalias(char *key
, char *key_alias
, int maxlen
);
254 extern int getdomainname(char *, int);
256 extern struct rpc_createerr rpc_createerr
;
257 extern CLIENT
*__yp_clnt_create_rsvdport();
260 main(int argc
, char **argv
)
262 unsigned long program
;
265 get_command_line_args(argc
, argv
);
268 get_default_domain_name();
275 if (yp_getalias(domain
, domain_alias
, NAME_MAX
) != 0)
276 fprintf(stderr
, "domain alias for %s not found\n", domain
);
277 if (yp_getalias(map
, map_alias
, MAXALIASLEN
) != 0)
278 fprintf(stderr
, "map alias for %s not found\n", map
);
280 /* check to see if the map exists in this domain */
282 sprintf(ypmapname
, "%s/%s/%s%s.dir", ypdbpath
, domain_alias
,
283 NTOL_PREFIX
, map_alias
);
285 sprintf(ypmapname
, "%s/%s/%s.dir", ypdbpath
, domain_alias
,
287 if (stat64(ypmapname
, &sbuf
) < 0) {
288 fprintf(stderr
, "yppush: Map does not exist.\n");
299 * All process exits after the call to generate_callback should be
300 * through listener_exit(program, status), not exit(status), so the
301 * transient server can get unregistered with the portmapper.
304 if (!generate_callback(&program
)) {
305 fprintf(stderr
, "Can't set up transient callback server.\n");
310 listener_exit(program
, 0);
317 * This does the command line parsing.
320 get_command_line_args(int argc
, char **argv
)
326 fprintf(stderr
, pusage
);
331 if ((*argv
)[0] == '-') {
332 switch ((*argv
)[1]) {
343 if (((int)strlen(domain
)) >
351 fprintf(stderr
, pusage
);
363 fprintf(stderr
, pusage
);
373 if (sscanf(*argv
, "%d", &curpar
) != 1) {
374 (void) fprintf(stderr
, pusage
);
379 (void) fprintf(stderr
, pusage
);
383 (void) fprintf(stderr
, pusage
);
389 fprintf(stderr
, pusage
);
396 fprintf(stderr
, pusage
);
404 fprintf(stderr
, pusage
);
410 * This gets the local kernel domainname, and sets the global domain to it.
413 get_default_domain_name(void)
415 if (!getdomainname(default_domain_name
, YPMAXDOMAIN
)) {
416 domain
= default_domain_name
;
418 fprintf(stderr
, err_cant_get_kname
, err_bad_domainname
);
422 if ((int)strlen(domain
) == 0) {
423 fprintf(stderr
, err_null_kname
, err_bad_domainname
);
429 * This verifies that the hostname supplied by the user is in the map
430 * "ypservers" then calls add_server to make it the only entry on the
441 char *ypservers
= "ypservers";
444 printf("Verifying YP server: %s\n", host
);
448 if (err
= yp_bind(domain_alias
)) {
449 fprintf(stderr
, err_cant_bind
, domain
, yperr_string(err
));
453 keylen
= strlen(host
);
455 if (yp_match(domain_alias
, ypservers
, host
, keylen
,
457 fprintf(stderr
, err_cant_find_host
, host
);
461 add_server(host
, keylen
);
465 * This uses yp operations to retrieve each server name in the map
466 * "ypservers". add_server is called for each one to add it to the list of
470 make_server_list(void)
479 char *ypservers
= "ypservers";
483 printf("Finding YP servers: ");
488 if (err
= yp_bind(domain_alias
)) {
489 fprintf(stderr
, err_cant_bind
, domain
, yperr_string(err
));
493 if (err
= yp_first(domain_alias
, ypservers
, &outkey
, &outkeylen
,
495 fprintf(stderr
, err_cant_build_serverlist
, yperr_string(err
));
500 add_server(outkey
, outkeylen
);
502 printf(" %s", outkey
);
513 if (err
= yp_next(domain_alias
, ypservers
, key
, keylen
,
514 &outkey
, &outkeylen
, &val
, &vallen
)) {
516 if (err
== YPERR_NOMORE
) {
519 fprintf(stderr
, err_cant_build_serverlist
,
534 * This adds a single server to the server list.
537 add_server(char *sname
, int namelen
)
540 static unsigned long seq
;
541 static unsigned long xactid
= 0;
543 if (strcmp(sname
, my_name
) == 0)
547 xactid_seed(&xactid
);
550 if ((ps
= (struct server
*)malloc((unsigned)sizeof (struct server
)))
551 == (struct server
*)NULL
) {
552 perror("yppush: malloc failure");
556 sname
[namelen
] = '\0';
557 strcpy(ps
->svc_name
, sname
);
558 ps
->state
= SSTAT_INIT
;
561 ps
->xactid
= xactid
+ seq
++;
562 ps
->pnext
= server_list
;
567 * This sets the base range for the transaction ids used in speaking the the
568 * server ypxfr processes.
571 xactid_seed(unsigned long *xactid
)
575 if (gettimeofday(&t
) == -1) {
576 perror("yppush gettimeofday failure");
584 * This generates the channel which will be used as the listener process'
585 * service rendezvous point, and comes up with a transient program number
586 * for the use of the RPC messages from the ypxfr processes.
589 generate_callback(unsigned long *program
)
591 unsigned long prognum
= 0x40000000, maxprognum
;
594 unsigned char b
[sizeof (unsigned long)];
597 struct netconfig
*nc4
, *nc6
, *nc
;
600 nc4
= getnetconfigent("udp");
601 nc6
= getnetconfigent("udp6");
602 if (nc4
== 0 && nc6
== 0) {
604 "yppush: Could not get udp or udp6 netconfig entry\n");
608 transport4
= (nc4
== 0) ? 0 : svc_tli_create(RPC_ANYFD
, nc4
, 0, 0, 0);
609 transport6
= (nc6
== 0) ? 0 : svc_tli_create(RPC_ANYFD
, nc6
, 0, 0, 0);
610 if (transport4
== 0 && transport6
== 0) {
611 fprintf(stderr
, "yppush: Could not create server handle(s)\n");
615 /* Find the maximum possible program number using an unsigned long */
616 for (i
= 0; i
< sizeof (u
.b
); i
++)
620 if (transport4
!= 0) {
627 while (prognum
< maxprognum
&& (ret
=
628 rpcb_set(prognum
, YPPUSHVERS
, nc
, &trans
->xp_ltaddr
)) == 0)
632 fprintf(stderr
, "yppush: Could not create callback service\n");
635 if (trans
== transport4
&& transport6
!= 0) {
636 ret
= rpcb_set(prognum
, YPPUSHVERS
, nc6
,
637 &transport6
->xp_ltaddr
);
640 "yppush: Could not create udp6 callback service\n");
651 * This is the main loop. Send messages to each server,
652 * and then wait for a response.
663 server_list
= server_list
->pnext
; /* delete from server_list */
664 ps
->pnext
= active_list
;
675 if (in
== active_list
) {
676 active_list
= active_list
->pnext
;
680 for (n
= active_list
; n
; n
= n
->pnext
) {
693 unsigned long program
;
695 pollfd_t
*pollset
= NULL
;
700 int hpar
; /* this times par count */
708 if (grace_period
< MIN_GRACE
)
709 grace_period
= MIN_GRACE
;
710 if (transport4
!= 0) {
711 if (!svc_reg(transport4
, program
, YPPUSHVERS
,
712 listener_dispatch
, 0)) {
714 "Can't set up transient udp callback server.\n");
717 if (transport6
!= 0) {
718 if (!svc_reg(transport6
, program
, YPPUSHVERS
,
719 listener_dispatch
, 0)) {
721 "Can't set up transient udp6 callback server.\n");
726 if (server_list
== NULL
) {
729 for (ps
= active_list
; ps
; ps
= ps
->pnext
)
730 if (ps
->state
== SSTAT_CALLED
) {
731 if ((time_now
- ps
->start_time
) <
739 printf("terminating %d dead\n", dead
);
743 for (ps
= active_list
; ps
; ps
= ps
->pnext
)
744 if (ps
->state
== SSTAT_CALLED
) {
745 if ((time_now
- ps
->start_time
)
749 "no response from %s -- grace of %d seconds expired.\n",
750 ps
->svc_name
, grace_period
);
754 "No response from ypxfr on %s\n", ps
->svc_name
);
761 for (ps
= active_list
; ps
; ps
= ps
->pnext
) {
762 if (ps
->state
== SSTAT_CALLED
) {
763 if ((time_now
- ps
->start_time
)
769 "No response yet from ypxfr on %s\n", ps
->svc_name
);
775 printf("Deactivating %s\n",
783 /* add someone to the active list keep up with curpar */
784 for (i
= 0; i
< (curpar
- actives
); i
++) {
785 if (add_to_active()) {
787 ps
->state
= send_message(ps
, program
, &error
);
788 print_state_msg(ps
, error
);
789 if (ps
->state
!= SSTAT_CALLED
)
790 delete_active(ps
); /* zorch it */
792 ps
->start_time
= time(0); /* set time */
796 for (ps
= active_list
; ps
; ps
= ps
->pnext
)
797 if (ps
->state
== SSTAT_CALLED
) {
803 printf("No one to wait for this pass.\n");
806 continue; /* try curpar more */
809 if (npollfds
!= svc_max_pollfd
) {
810 pollset
= realloc(pollset
,
811 sizeof (pollfd_t
) * svc_max_pollfd
);
812 npollfds
= svc_max_pollfd
;
816 * Get existing array of pollfd's, should really compress
817 * this but it shouldn't get very large (or sparse).
819 (void) memcpy(pollset
, svc_pollfd
,
820 sizeof (pollfd_t
) * svc_max_pollfd
);
823 switch (pollret
= poll(pollset
, npollfds
, MIN_GRACE
* 1000)) {
825 if (errno
!= EINTR
) {
826 (void) perror("main loop select");
832 (void) printf("timeout in main loop select.\n");
838 svc_getreq_poll(pollset
, pollret
);
845 * This does the listener process cleanup and process exit.
848 listener_exit(unsigned long program
, int stat
)
850 svc_unreg(program
, YPPUSHVERS
);
855 * This is the listener process' RPC service dispatcher.
858 listener_dispatch(struct svc_req
*rqstp
, SVCXPRT
*transp
)
860 switch (rqstp
->rq_proc
) {
862 case YPPUSHPROC_NULL
:
863 if (!svc_sendreply(transp
, xdr_void
, 0)) {
864 fprintf(stderr
, "Can't reply to rpc call.\n");
868 case YPPUSHPROC_XFRRESP
:
869 get_xfr_response(transp
);
873 svcerr_noproc(transp
);
880 * This dumps a server state message to stdout. It is called in cases where
881 * we have no expectation of receiving a callback from the remote ypxfr.
884 print_state_msg(struct server
*s
, long e
)
886 struct state_duple
*sd
;
888 if (s
->state
== SSTAT_SYSTEM
)
889 return; /* already printed */
891 if (!verbose
&& (s
->state
== SSTAT_RESPONDED
||
892 s
->state
== SSTAT_CALLED
))
895 for (sd
= state_duples
; sd
->state_msg
; sd
++) {
896 if (sd
->state
== s
->state
) {
897 printf(sd
->state_msg
, s
->svc_name
);
899 if (s
->state
== SSTAT_RPC
) {
900 rpcerr_msg((enum clnt_stat
) e
);
909 fprintf(stderr
, "yppush: Bad server state value %d.\n", s
->state
);
913 * This dumps a transfer status message to stdout. It is called in
914 * response to a received RPC message from the called ypxfr.
917 print_callback_msg(struct server
*s
)
919 register struct status_duple
*sd
;
922 (s
->status
== YPPUSH_AGE
) ||
923 (s
->status
== YPPUSH_SUCC
))
927 for (sd
= status_duples
; sd
->status_msg
; sd
++) {
929 if (sd
->status
== s
->status
) {
930 printf("Status received from ypxfr on %s:\n\t%s\n",
931 s
->svc_name
, sd
->status_msg
);
937 fprintf(stderr
, "yppush listener: Garbage transaction "
938 "status (value %d) from ypxfr on %s.\n",
939 (int)s
->status
, s
->svc_name
);
943 * This dumps an RPC error message to stdout. This is basically a rewrite
944 * of clnt_perrno, but writes to stdout instead of stderr.
947 rpcerr_msg(enum clnt_stat e
)
949 struct rpcerr_duple
*rd
;
951 for (rd
= rpcerr_duples
; rd
->rpc_msg
; rd
++) {
953 if (rd
->rpc_stat
== e
) {
959 fprintf(stderr
, "Bad error code passed to rpcerr_msg: %d.\n", e
);
963 * This picks up the response from the ypxfr process which has been started
964 * up on the remote node. The response status must be non-zero, otherwise
965 * the status will be set to "ypxfr error".
968 get_xfr_response(SVCXPRT
*transp
)
970 struct yppushresp_xfr resp
;
971 register struct server
*s
;
973 if (!svc_getargs(transp
, (xdrproc_t
)xdr_yppushresp_xfr
,
975 svcerr_decode(transp
);
979 if (!svc_sendreply(transp
, xdr_void
, 0)) {
980 (void) fprintf(stderr
, "Can't reply to rpc call.\n");
983 for (s
= active_list
; s
; s
= s
->pnext
) {
985 if (s
->xactid
== resp
.transid
) {
986 s
->status
= resp
.status
? resp
.status
: YPPUSH_XFRERR
;
987 print_callback_msg(s
);
988 s
->state
= SSTAT_RESPONDED
;
995 * This sends a message to a single ypserv process. The return value is
996 * a state value. If the RPC call fails because of a version
997 * mismatch, we'll assume that we're talking to a version 1 ypserv process,
998 * and will send it an old "YPPROC_GET" request, as was defined in the
999 * earlier version of yp_prot.h
1001 static unsigned short
1002 send_message(struct server
*ps
, unsigned long program
, long *err
)
1004 struct ypreq_newxfr req
;
1005 struct ypreq_xfr oldreq
;
1007 struct rpc_err rpcerr
;
1009 if ((ps
->domb
.dom_client
= __yp_clnt_create_rsvdport(ps
->svc_name
,
1010 YPPROG
, YPVERS
, (char *)NULL
, 0, 0)) == NULL
) {
1012 if (rpc_createerr
.cf_stat
== RPC_PROGNOTREGISTERED
) {
1013 return (SSTAT_PROGNOTREG
);
1015 printf("Error talking to %s: ", ps
->svc_name
);
1016 rpcerr_msg(rpc_createerr
.cf_stat
);
1019 return (SSTAT_SYSTEM
);
1023 if (sysinfo(SI_HOSTNAME
, my_name
, sizeof (my_name
)) == -1) {
1024 return (SSTAT_RSCRC
);
1028 req
.ypxfr_domain
= domain
;
1029 req
.ypxfr_map
= map
;
1030 req
.ypxfr_ordernum
= 0;
1031 req
.ypxfr_owner
= my_name
;
1032 req
.name
= ps
->svc_name
;
1034 * the creation of field req.name, instead of ypreq_xfr (old)
1035 * req.port, does not make any sense. it doesn't give any
1036 * information to receiving ypserv except its own name !!
1037 * new ypserv duplicates work for YPPROC_XFR and YPPROC_NEWXFR
1039 req
.transid
= ps
->xactid
;
1040 req
.proto
= program
;
1041 s
= (enum clnt_stat
) clnt_call(ps
->domb
.dom_client
,
1042 YPPROC_NEWXFR
, (xdrproc_t
)xdr_ypreq_newxfr
, (caddr_t
)&req
,
1043 xdr_void
, 0, timeout
);
1046 clnt_geterr(ps
->domb
.dom_client
, &rpcerr
);
1048 if (s
== RPC_PROCUNAVAIL
) {
1049 oldreq
.ypxfr_domain
= domain
;
1050 oldreq
.ypxfr_map
= map
;
1051 oldreq
.ypxfr_ordernum
= 0;
1052 oldreq
.ypxfr_owner
= my_name
;
1053 oldreq
.transid
= ps
->xactid
;
1054 oldreq
.proto
= program
;
1056 s
= (enum clnt_stat
) clnt_call(ps
->domb
.dom_client
,
1057 YPPROC_XFR
, (xdrproc_t
)xdr_ypreq_xfr
, (caddr_t
)&oldreq
,
1058 xdr_void
, 0, timeout
);
1059 clnt_geterr(ps
->domb
.dom_client
, &rpcerr
);
1062 clnt_destroy(ps
->domb
.dom_client
);
1064 if (s
== RPC_SUCCESS
) {
1065 return (SSTAT_CALLED
);
1067 *err
= (long)rpcerr
.re_status
;
1074 * FUNCTION: is_yptol_mode();
1076 * DESCRIPTION: Determines if we should run in N2L or traditional mode based
1077 * on the presence of the N2L mapping file.
1079 * This is a copy of a function from libnisdb. If more than this
1080 * one function become required it may be worth linking the
1085 * OUTPUTS: TRUE = Run in N2L mode
1086 * FALSE = Run in traditional mode.
1091 struct stat filestat
;
1093 if (stat(NTOL_MAP_FILE
, &filestat
) != -1)