1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate * 22*7c478bd9Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 23*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 24*7c478bd9Sstevel@tonic-gate * 25*7c478bd9Sstevel@tonic-gate * Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T 26*7c478bd9Sstevel@tonic-gate * All Rights Reserved 27*7c478bd9Sstevel@tonic-gate * 28*7c478bd9Sstevel@tonic-gate * Portions of this source code were derived from Berkeley 29*7c478bd9Sstevel@tonic-gate * 4.3 BSD under license from the Regents of the University of 30*7c478bd9Sstevel@tonic-gate * California. 31*7c478bd9Sstevel@tonic-gate */ 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate #define _SVID_GETTOD 36*7c478bd9Sstevel@tonic-gate #include <sys/time.h> 37*7c478bd9Sstevel@tonic-gate extern int gettimeofday(struct timeval *); 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 40*7c478bd9Sstevel@tonic-gate #include <stdio.h> 41*7c478bd9Sstevel@tonic-gate #include <string.h> 42*7c478bd9Sstevel@tonic-gate #include <malloc.h> 43*7c478bd9Sstevel@tonic-gate #include <errno.h> 44*7c478bd9Sstevel@tonic-gate #include <signal.h> 45*7c478bd9Sstevel@tonic-gate #include <limits.h> 46*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 47*7c478bd9Sstevel@tonic-gate #include <unistd.h> 48*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 49*7c478bd9Sstevel@tonic-gate #include <sys/wait.h> 50*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 51*7c478bd9Sstevel@tonic-gate #include <ctype.h> 52*7c478bd9Sstevel@tonic-gate #include <dirent.h> 53*7c478bd9Sstevel@tonic-gate #include <rpc/rpc.h> 54*7c478bd9Sstevel@tonic-gate #include <rpc/nettype.h> 55*7c478bd9Sstevel@tonic-gate #include <rpc/rpcb_prot.h> 56*7c478bd9Sstevel@tonic-gate #include <rpc/rpcb_clnt.h> 57*7c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h> 58*7c478bd9Sstevel@tonic-gate #include <sys/select.h> 59*7c478bd9Sstevel@tonic-gate #include "ypsym.h" 60*7c478bd9Sstevel@tonic-gate #include "ypdefs.h" 61*7c478bd9Sstevel@tonic-gate #include "yp_b.h" 62*7c478bd9Sstevel@tonic-gate #include "shim.h" 63*7c478bd9Sstevel@tonic-gate #include "yptol.h" 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 67*7c478bd9Sstevel@tonic-gate #undef YPPROG 68*7c478bd9Sstevel@tonic-gate #define YPPROG ((ulong_t)109999) 69*7c478bd9Sstevel@tonic-gate #undef YPBINDPROG 70*7c478bd9Sstevel@tonic-gate #define YPBINDPROG ((ulong_t)109998) 71*7c478bd9Sstevel@tonic-gate #endif 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate #define INTER_TRY 12 /* Seconds between tries */ 74*7c478bd9Sstevel@tonic-gate #define PORTMAP_TIME 30 /* Seconds before decide its down */ 75*7c478bd9Sstevel@tonic-gate #define TIMEOUT INTER_TRY*4 /* Total time for timeout */ 76*7c478bd9Sstevel@tonic-gate #define CUR_PAR 4 /* Total parallal yppushes */ 77*7c478bd9Sstevel@tonic-gate #define MIN_GRACE 25 /* select timeout and minimum grace */ 78*7c478bd9Sstevel@tonic-gate #define GRACE_PERIOD 800 /* Total seconds we'll wait for */ 79*7c478bd9Sstevel@tonic-gate /* responses from ypxfrs, yes */ 80*7c478bd9Sstevel@tonic-gate /* virginia yp map transfers */ 81*7c478bd9Sstevel@tonic-gate /* can take a long time, we */ 82*7c478bd9Sstevel@tonic-gate /* only worry if the slave */ 83*7c478bd9Sstevel@tonic-gate /* crashes ... */ 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate USE_YPDBPATH 86*7c478bd9Sstevel@tonic-gate static char *pusage; 87*7c478bd9Sstevel@tonic-gate static char *domain = NULL; 88*7c478bd9Sstevel@tonic-gate static char *host = NULL; 89*7c478bd9Sstevel@tonic-gate static char my_name[YPMAXPEER +1]; 90*7c478bd9Sstevel@tonic-gate static char default_domain_name[YPMAXDOMAIN]; 91*7c478bd9Sstevel@tonic-gate static char domain_alias[MAXNAMLEN]; /* nickname for domain - */ 92*7c478bd9Sstevel@tonic-gate /* used in sysv filesystems */ 93*7c478bd9Sstevel@tonic-gate static char map_alias[MAXNAMLEN]; /* nickname for map - */ 94*7c478bd9Sstevel@tonic-gate /* used in sysv filesystems */ 95*7c478bd9Sstevel@tonic-gate static char *map = NULL; 96*7c478bd9Sstevel@tonic-gate static bool verbose = FALSE; 97*7c478bd9Sstevel@tonic-gate static bool onehost = FALSE; 98*7c478bd9Sstevel@tonic-gate static bool oldxfr = FALSE; 99*7c478bd9Sstevel@tonic-gate static bool callback_timeout = FALSE; /* set when a callback times out */ 100*7c478bd9Sstevel@tonic-gate int grace_period = GRACE_PERIOD; 101*7c478bd9Sstevel@tonic-gate int curpar = CUR_PAR; /* should be set by other stuff */ 102*7c478bd9Sstevel@tonic-gate static char ypmapname[1024]; /* Used to check for map's existence */ 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate static struct timeval intertry = { 105*7c478bd9Sstevel@tonic-gate INTER_TRY, /* Seconds */ 106*7c478bd9Sstevel@tonic-gate 0 /* Microseconds */ 107*7c478bd9Sstevel@tonic-gate }; 108*7c478bd9Sstevel@tonic-gate static struct timeval timeout = { 109*7c478bd9Sstevel@tonic-gate TIMEOUT, /* Seconds */ 110*7c478bd9Sstevel@tonic-gate 0 /* Microseconds */ 111*7c478bd9Sstevel@tonic-gate }; 112*7c478bd9Sstevel@tonic-gate static SVCXPRT *transport4; 113*7c478bd9Sstevel@tonic-gate static SVCXPRT *transport6; 114*7c478bd9Sstevel@tonic-gate struct server { 115*7c478bd9Sstevel@tonic-gate struct server *pnext; 116*7c478bd9Sstevel@tonic-gate struct dom_binding domb; 117*7c478bd9Sstevel@tonic-gate char svc_name[YPMAXPEER+1]; 118*7c478bd9Sstevel@tonic-gate unsigned long xactid; 119*7c478bd9Sstevel@tonic-gate unsigned short state; 120*7c478bd9Sstevel@tonic-gate unsigned long status; 121*7c478bd9Sstevel@tonic-gate bool oldvers; 122*7c478bd9Sstevel@tonic-gate int start_time; 123*7c478bd9Sstevel@tonic-gate }; 124*7c478bd9Sstevel@tonic-gate #define n_conf dom_binding->ypbind_nconf 125*7c478bd9Sstevel@tonic-gate #define svc_addr dom_binding->ypbind_svcaddr 126*7c478bd9Sstevel@tonic-gate static struct server *server_list = (struct server *)NULL; 127*7c478bd9Sstevel@tonic-gate static struct server *active_list = (struct server *)NULL; 128*7c478bd9Sstevel@tonic-gate 129*7c478bd9Sstevel@tonic-gate /* State values for server.state field */ 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate #define SSTAT_INIT 0 132*7c478bd9Sstevel@tonic-gate #define SSTAT_CALLED 1 133*7c478bd9Sstevel@tonic-gate #define SSTAT_RESPONDED 2 134*7c478bd9Sstevel@tonic-gate #define SSTAT_PROGNOTREG 3 135*7c478bd9Sstevel@tonic-gate #define SSTAT_RPC 4 136*7c478bd9Sstevel@tonic-gate #define SSTAT_RSCRC 5 137*7c478bd9Sstevel@tonic-gate #define SSTAT_SYSTEM 6 138*7c478bd9Sstevel@tonic-gate 139*7c478bd9Sstevel@tonic-gate static char err_usage[] = 140*7c478bd9Sstevel@tonic-gate "Usage:\n\typpush [-p <par>] [-d <domainname>] [-h <hostname>] [-v] map\n"; 141*7c478bd9Sstevel@tonic-gate static char err_bad_args[] = 142*7c478bd9Sstevel@tonic-gate "The %s argument is bad.\n"; 143*7c478bd9Sstevel@tonic-gate static char err_cant_get_kname[] = 144*7c478bd9Sstevel@tonic-gate "Can't get %s from system call.\n"; 145*7c478bd9Sstevel@tonic-gate static char err_null_kname[] = 146*7c478bd9Sstevel@tonic-gate "The %s hasn't been set on this machine.\n"; 147*7c478bd9Sstevel@tonic-gate static char err_bad_domainname[] = "domainname"; 148*7c478bd9Sstevel@tonic-gate static char err_cant_bind[] = 149*7c478bd9Sstevel@tonic-gate "Can't find a yp server for domain %s. Reason: %s.\n"; 150*7c478bd9Sstevel@tonic-gate static char err_cant_build_serverlist[] = 151*7c478bd9Sstevel@tonic-gate "Can't build server list from map \"ypservers\". Reason: %s.\n"; 152*7c478bd9Sstevel@tonic-gate static char err_cant_find_host[] = 153*7c478bd9Sstevel@tonic-gate "Can't find host %s in map \"ypservers\".\n"; 154*7c478bd9Sstevel@tonic-gate /* 155*7c478bd9Sstevel@tonic-gate * State_duple table. All messages should take 1 arg - the node name. 156*7c478bd9Sstevel@tonic-gate */ 157*7c478bd9Sstevel@tonic-gate struct state_duple { 158*7c478bd9Sstevel@tonic-gate int state; 159*7c478bd9Sstevel@tonic-gate char *state_msg; 160*7c478bd9Sstevel@tonic-gate }; 161*7c478bd9Sstevel@tonic-gate static struct state_duple state_duples[] = { 162*7c478bd9Sstevel@tonic-gate {SSTAT_INIT, "Internal error trying to talk to %s."}, 163*7c478bd9Sstevel@tonic-gate {SSTAT_CALLED, "%s has been called."}, 164*7c478bd9Sstevel@tonic-gate {SSTAT_RESPONDED, "%s (v1 ypserv) sent an old-style request."}, 165*7c478bd9Sstevel@tonic-gate {SSTAT_PROGNOTREG, "nis server not registered at %s."}, 166*7c478bd9Sstevel@tonic-gate {SSTAT_RPC, "RPC error to %s: "}, 167*7c478bd9Sstevel@tonic-gate {SSTAT_RSCRC, "Local resource allocation failure - can't talk to %s."}, 168*7c478bd9Sstevel@tonic-gate {SSTAT_SYSTEM, "System error talking to %s: "}, 169*7c478bd9Sstevel@tonic-gate {0, (char *)NULL} 170*7c478bd9Sstevel@tonic-gate }; 171*7c478bd9Sstevel@tonic-gate /* 172*7c478bd9Sstevel@tonic-gate * Status_duple table. No messages should require any args. 173*7c478bd9Sstevel@tonic-gate */ 174*7c478bd9Sstevel@tonic-gate static struct status_duple { 175*7c478bd9Sstevel@tonic-gate long status; 176*7c478bd9Sstevel@tonic-gate char *status_msg; 177*7c478bd9Sstevel@tonic-gate }; 178*7c478bd9Sstevel@tonic-gate static struct status_duple status_duples[] = { 179*7c478bd9Sstevel@tonic-gate {YPPUSH_SUCC, "Map successfully transferred."}, 180*7c478bd9Sstevel@tonic-gate {YPPUSH_AGE, 181*7c478bd9Sstevel@tonic-gate "Transfer not done: master's version isn't newer."}, 182*7c478bd9Sstevel@tonic-gate {YPPUSH_NOMAP, "Failed - ypxfr there can't find a server for map."}, 183*7c478bd9Sstevel@tonic-gate {YPPUSH_NODOM, "Failed - domain isn't supported."}, 184*7c478bd9Sstevel@tonic-gate {YPPUSH_RSRC, "Failed - local resource allocation failure."}, 185*7c478bd9Sstevel@tonic-gate {YPPUSH_RPC, "Failed - ypxfr had an RPC failure"}, 186*7c478bd9Sstevel@tonic-gate {YPPUSH_MADDR, "Failed - ypxfr couldn't get the map master's address."}, 187*7c478bd9Sstevel@tonic-gate {YPPUSH_YPERR, "Failed - nis server or map format error."}, 188*7c478bd9Sstevel@tonic-gate {YPPUSH_BADARGS, "Failed - args to ypxfr were bad."}, 189*7c478bd9Sstevel@tonic-gate {YPPUSH_DBM, "Failed - dbm operation on map failed."}, 190*7c478bd9Sstevel@tonic-gate {YPPUSH_FILE, "Failed - file I/O operation on map failed"}, 191*7c478bd9Sstevel@tonic-gate {YPPUSH_SKEW, "Failed - map version skew during transfer."}, 192*7c478bd9Sstevel@tonic-gate {YPPUSH_CLEAR, 193*7c478bd9Sstevel@tonic-gate "Map successfully transferred, but ypxfr \ 194*7c478bd9Sstevel@tonic-gate couldn't send \"Clear map\" to ypserv "}, 195*7c478bd9Sstevel@tonic-gate {YPPUSH_FORCE, 196*7c478bd9Sstevel@tonic-gate "Failed - no local order number in map - use -f flag to ypxfr."}, 197*7c478bd9Sstevel@tonic-gate {YPPUSH_XFRERR, "Failed - ypxfr internal error."}, 198*7c478bd9Sstevel@tonic-gate {YPPUSH_REFUSED, "Failed - Transfer request refused."}, 199*7c478bd9Sstevel@tonic-gate {YPPUSH_NOALIAS, 200*7c478bd9Sstevel@tonic-gate "Failed - System V domain/map alias not in alias file."}, 201*7c478bd9Sstevel@tonic-gate {0, (char *)NULL} 202*7c478bd9Sstevel@tonic-gate }; 203*7c478bd9Sstevel@tonic-gate /* 204*7c478bd9Sstevel@tonic-gate * rpcerr_duple table 205*7c478bd9Sstevel@tonic-gate */ 206*7c478bd9Sstevel@tonic-gate static struct rpcerr_duple { 207*7c478bd9Sstevel@tonic-gate enum clnt_stat rpc_stat; 208*7c478bd9Sstevel@tonic-gate char *rpc_msg; 209*7c478bd9Sstevel@tonic-gate }; 210*7c478bd9Sstevel@tonic-gate static struct rpcerr_duple rpcerr_duples[] = { 211*7c478bd9Sstevel@tonic-gate {RPC_SUCCESS, "RPC success"}, 212*7c478bd9Sstevel@tonic-gate {RPC_CANTENCODEARGS, "RPC Can't encode args"}, 213*7c478bd9Sstevel@tonic-gate {RPC_CANTDECODERES, "RPC Can't decode results"}, 214*7c478bd9Sstevel@tonic-gate {RPC_CANTSEND, "RPC Can't send"}, 215*7c478bd9Sstevel@tonic-gate {RPC_CANTRECV, "RPC Can't recv"}, 216*7c478bd9Sstevel@tonic-gate {RPC_TIMEDOUT, "NIS server registered, but does not respond"}, 217*7c478bd9Sstevel@tonic-gate {RPC_VERSMISMATCH, "RPC version mismatch"}, 218*7c478bd9Sstevel@tonic-gate {RPC_AUTHERROR, "RPC auth error"}, 219*7c478bd9Sstevel@tonic-gate {RPC_PROGUNAVAIL, "RPC remote program unavailable"}, 220*7c478bd9Sstevel@tonic-gate {RPC_PROGVERSMISMATCH, "RPC program mismatch"}, 221*7c478bd9Sstevel@tonic-gate {RPC_PROCUNAVAIL, "RPC unknown procedure"}, 222*7c478bd9Sstevel@tonic-gate {RPC_CANTDECODEARGS, "RPC Can't decode args"}, 223*7c478bd9Sstevel@tonic-gate {RPC_UNKNOWNHOST, "unknown host"}, 224*7c478bd9Sstevel@tonic-gate {RPC_RPCBFAILURE, "rpcbind failure (host is down?)"}, 225*7c478bd9Sstevel@tonic-gate {RPC_PROGNOTREGISTERED, "RPC prog not registered"}, 226*7c478bd9Sstevel@tonic-gate {RPC_SYSTEMERROR, "RPC system error"}, 227*7c478bd9Sstevel@tonic-gate {RPC_SUCCESS, (char *)NULL} /* Duplicate rpc_stat */ 228*7c478bd9Sstevel@tonic-gate /* unused in list-end */ 229*7c478bd9Sstevel@tonic-gate /* entry */ 230*7c478bd9Sstevel@tonic-gate }; 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate static void get_default_domain_name(void); 233*7c478bd9Sstevel@tonic-gate static void get_command_line_args(int argc, char **argv); 234*7c478bd9Sstevel@tonic-gate static unsigned short send_message(struct server *ps, 235*7c478bd9Sstevel@tonic-gate unsigned long program, long *err); 236*7c478bd9Sstevel@tonic-gate static void make_server_list(void); 237*7c478bd9Sstevel@tonic-gate static void one_host_list(void); 238*7c478bd9Sstevel@tonic-gate static void add_server(char *sname, int namelen); 239*7c478bd9Sstevel@tonic-gate static int generate_callback(unsigned long *program); 240*7c478bd9Sstevel@tonic-gate static void xactid_seed(unsigned long *xactid); 241*7c478bd9Sstevel@tonic-gate static void main_loop(unsigned long program); 242*7c478bd9Sstevel@tonic-gate static void listener_exit(unsigned long program, int stat); 243*7c478bd9Sstevel@tonic-gate static void listener_dispatch(struct svc_req *rqstp, SVCXPRT *transp); 244*7c478bd9Sstevel@tonic-gate static void print_state_msg(struct server *s, long e); 245*7c478bd9Sstevel@tonic-gate static void print_callback_msg(struct server *s); 246*7c478bd9Sstevel@tonic-gate static void rpcerr_msg(enum clnt_stat e); 247*7c478bd9Sstevel@tonic-gate static void get_xfr_response(SVCXPRT *transp); 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate #ifdef SYSVCONFIG 250*7c478bd9Sstevel@tonic-gate extern void sysvconfig(void); 251*7c478bd9Sstevel@tonic-gate #endif 252*7c478bd9Sstevel@tonic-gate extern int yp_getalias(char *key, char *key_alias, int maxlen); 253*7c478bd9Sstevel@tonic-gate extern int getdomainname(char *, int); 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate extern struct rpc_createerr rpc_createerr; 256*7c478bd9Sstevel@tonic-gate extern char *sys_errlist[]; 257*7c478bd9Sstevel@tonic-gate extern int sys_nerr; 258*7c478bd9Sstevel@tonic-gate extern CLIENT *__yp_clnt_create_rsvdport(); 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate int 261*7c478bd9Sstevel@tonic-gate main(int argc, char **argv) 262*7c478bd9Sstevel@tonic-gate { 263*7c478bd9Sstevel@tonic-gate unsigned long program; 264*7c478bd9Sstevel@tonic-gate struct stat sbuf; 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate get_command_line_args(argc, argv); 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate if (!domain) { 269*7c478bd9Sstevel@tonic-gate get_default_domain_name(); 270*7c478bd9Sstevel@tonic-gate } 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate #ifdef SYSVCONFIG 273*7c478bd9Sstevel@tonic-gate sysvconfig(); 274*7c478bd9Sstevel@tonic-gate #endif 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate if (yp_getalias(domain, domain_alias, NAME_MAX) != 0) 277*7c478bd9Sstevel@tonic-gate fprintf(stderr, "domain alias for %s not found\n", domain); 278*7c478bd9Sstevel@tonic-gate if (yp_getalias(map, map_alias, MAXALIASLEN) != 0) 279*7c478bd9Sstevel@tonic-gate fprintf(stderr, "map alias for %s not found\n", map); 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate /* check to see if the map exists in this domain */ 282*7c478bd9Sstevel@tonic-gate if (is_yptol_mode()) 283*7c478bd9Sstevel@tonic-gate sprintf(ypmapname, "%s/%s/%s%s.dir", ypdbpath, domain_alias, 284*7c478bd9Sstevel@tonic-gate NTOL_PREFIX, map_alias); 285*7c478bd9Sstevel@tonic-gate else 286*7c478bd9Sstevel@tonic-gate sprintf(ypmapname, "%s/%s/%s.dir", ypdbpath, domain_alias, 287*7c478bd9Sstevel@tonic-gate map_alias); 288*7c478bd9Sstevel@tonic-gate if (stat(ypmapname, &sbuf) < 0) { 289*7c478bd9Sstevel@tonic-gate fprintf(stderr, "yppush: Map does not exist.\n"); 290*7c478bd9Sstevel@tonic-gate exit(1); 291*7c478bd9Sstevel@tonic-gate } 292*7c478bd9Sstevel@tonic-gate 293*7c478bd9Sstevel@tonic-gate if (onehost) { 294*7c478bd9Sstevel@tonic-gate one_host_list(); 295*7c478bd9Sstevel@tonic-gate } else { 296*7c478bd9Sstevel@tonic-gate make_server_list(); 297*7c478bd9Sstevel@tonic-gate } 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate /* 300*7c478bd9Sstevel@tonic-gate * All process exits after the call to generate_callback should be 301*7c478bd9Sstevel@tonic-gate * through listener_exit(program, status), not exit(status), so the 302*7c478bd9Sstevel@tonic-gate * transient server can get unregistered with the portmapper. 303*7c478bd9Sstevel@tonic-gate */ 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate if (!generate_callback(&program)) { 306*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Can't set up transient callback server.\n"); 307*7c478bd9Sstevel@tonic-gate } 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate main_loop(program); 310*7c478bd9Sstevel@tonic-gate 311*7c478bd9Sstevel@tonic-gate listener_exit(program, 0); 312*7c478bd9Sstevel@tonic-gate 313*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 314*7c478bd9Sstevel@tonic-gate return (0); 315*7c478bd9Sstevel@tonic-gate } 316*7c478bd9Sstevel@tonic-gate 317*7c478bd9Sstevel@tonic-gate /* 318*7c478bd9Sstevel@tonic-gate * This does the command line parsing. 319*7c478bd9Sstevel@tonic-gate */ 320*7c478bd9Sstevel@tonic-gate static void 321*7c478bd9Sstevel@tonic-gate get_command_line_args(int argc, char **argv) 322*7c478bd9Sstevel@tonic-gate { 323*7c478bd9Sstevel@tonic-gate pusage = err_usage; 324*7c478bd9Sstevel@tonic-gate argv++; 325*7c478bd9Sstevel@tonic-gate 326*7c478bd9Sstevel@tonic-gate if (argc < 2) { 327*7c478bd9Sstevel@tonic-gate fprintf(stderr, pusage); 328*7c478bd9Sstevel@tonic-gate exit(1); 329*7c478bd9Sstevel@tonic-gate } 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate while (--argc) { 332*7c478bd9Sstevel@tonic-gate if ((*argv)[0] == '-') { 333*7c478bd9Sstevel@tonic-gate switch ((*argv)[1]) { 334*7c478bd9Sstevel@tonic-gate case 'v': 335*7c478bd9Sstevel@tonic-gate verbose = TRUE; 336*7c478bd9Sstevel@tonic-gate argv++; 337*7c478bd9Sstevel@tonic-gate break; 338*7c478bd9Sstevel@tonic-gate case 'd': 339*7c478bd9Sstevel@tonic-gate if (argc > 1) { 340*7c478bd9Sstevel@tonic-gate argv++; 341*7c478bd9Sstevel@tonic-gate argc--; 342*7c478bd9Sstevel@tonic-gate domain = *argv; 343*7c478bd9Sstevel@tonic-gate argv++; 344*7c478bd9Sstevel@tonic-gate if (((int)strlen(domain)) > 345*7c478bd9Sstevel@tonic-gate YPMAXDOMAIN) { 346*7c478bd9Sstevel@tonic-gate fprintf(stderr, 347*7c478bd9Sstevel@tonic-gate err_bad_args, 348*7c478bd9Sstevel@tonic-gate err_bad_domainname); 349*7c478bd9Sstevel@tonic-gate exit(1); 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate } else { 352*7c478bd9Sstevel@tonic-gate fprintf(stderr, pusage); 353*7c478bd9Sstevel@tonic-gate exit(1); 354*7c478bd9Sstevel@tonic-gate } 355*7c478bd9Sstevel@tonic-gate break; 356*7c478bd9Sstevel@tonic-gate case 'h': 357*7c478bd9Sstevel@tonic-gate if (argc > 1) { 358*7c478bd9Sstevel@tonic-gate onehost = TRUE; 359*7c478bd9Sstevel@tonic-gate argv++; 360*7c478bd9Sstevel@tonic-gate argc--; 361*7c478bd9Sstevel@tonic-gate host = *argv; 362*7c478bd9Sstevel@tonic-gate argv++; 363*7c478bd9Sstevel@tonic-gate } else { 364*7c478bd9Sstevel@tonic-gate fprintf(stderr, pusage); 365*7c478bd9Sstevel@tonic-gate exit(1); 366*7c478bd9Sstevel@tonic-gate } 367*7c478bd9Sstevel@tonic-gate break; 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate case 'p': 370*7c478bd9Sstevel@tonic-gate 371*7c478bd9Sstevel@tonic-gate if (argc > 1) { 372*7c478bd9Sstevel@tonic-gate argv++; 373*7c478bd9Sstevel@tonic-gate argc--; 374*7c478bd9Sstevel@tonic-gate if (sscanf(*argv, "%d", &curpar) != 1) { 375*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, pusage); 376*7c478bd9Sstevel@tonic-gate exit(1); 377*7c478bd9Sstevel@tonic-gate } 378*7c478bd9Sstevel@tonic-gate argv++; 379*7c478bd9Sstevel@tonic-gate if (curpar < 1) { 380*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, pusage); 381*7c478bd9Sstevel@tonic-gate exit(1); 382*7c478bd9Sstevel@tonic-gate } 383*7c478bd9Sstevel@tonic-gate } else { 384*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, pusage); 385*7c478bd9Sstevel@tonic-gate exit(1); 386*7c478bd9Sstevel@tonic-gate } 387*7c478bd9Sstevel@tonic-gate break; 388*7c478bd9Sstevel@tonic-gate 389*7c478bd9Sstevel@tonic-gate default: 390*7c478bd9Sstevel@tonic-gate fprintf(stderr, pusage); 391*7c478bd9Sstevel@tonic-gate exit(1); 392*7c478bd9Sstevel@tonic-gate } 393*7c478bd9Sstevel@tonic-gate } else { 394*7c478bd9Sstevel@tonic-gate if (!map) { 395*7c478bd9Sstevel@tonic-gate map = *argv; 396*7c478bd9Sstevel@tonic-gate } else { 397*7c478bd9Sstevel@tonic-gate fprintf(stderr, pusage); 398*7c478bd9Sstevel@tonic-gate exit(1); 399*7c478bd9Sstevel@tonic-gate } 400*7c478bd9Sstevel@tonic-gate argv++; 401*7c478bd9Sstevel@tonic-gate } 402*7c478bd9Sstevel@tonic-gate } 403*7c478bd9Sstevel@tonic-gate 404*7c478bd9Sstevel@tonic-gate if (!map) { 405*7c478bd9Sstevel@tonic-gate fprintf(stderr, pusage); 406*7c478bd9Sstevel@tonic-gate exit(1); 407*7c478bd9Sstevel@tonic-gate } 408*7c478bd9Sstevel@tonic-gate } 409*7c478bd9Sstevel@tonic-gate 410*7c478bd9Sstevel@tonic-gate /* 411*7c478bd9Sstevel@tonic-gate * This gets the local kernel domainname, and sets the global domain to it. 412*7c478bd9Sstevel@tonic-gate */ 413*7c478bd9Sstevel@tonic-gate static void 414*7c478bd9Sstevel@tonic-gate get_default_domain_name(void) 415*7c478bd9Sstevel@tonic-gate { 416*7c478bd9Sstevel@tonic-gate if (!getdomainname(default_domain_name, YPMAXDOMAIN)) { 417*7c478bd9Sstevel@tonic-gate domain = default_domain_name; 418*7c478bd9Sstevel@tonic-gate } else { 419*7c478bd9Sstevel@tonic-gate fprintf(stderr, err_cant_get_kname, err_bad_domainname); 420*7c478bd9Sstevel@tonic-gate exit(1); 421*7c478bd9Sstevel@tonic-gate } 422*7c478bd9Sstevel@tonic-gate 423*7c478bd9Sstevel@tonic-gate if ((int)strlen(domain) == 0) { 424*7c478bd9Sstevel@tonic-gate fprintf(stderr, err_null_kname, err_bad_domainname); 425*7c478bd9Sstevel@tonic-gate exit(1); 426*7c478bd9Sstevel@tonic-gate } 427*7c478bd9Sstevel@tonic-gate } 428*7c478bd9Sstevel@tonic-gate 429*7c478bd9Sstevel@tonic-gate /* 430*7c478bd9Sstevel@tonic-gate * This verifies that the hostname supplied by the user is in the map 431*7c478bd9Sstevel@tonic-gate * "ypservers" then calls add_server to make it the only entry on the 432*7c478bd9Sstevel@tonic-gate * list of servers. 433*7c478bd9Sstevel@tonic-gate */ 434*7c478bd9Sstevel@tonic-gate static void 435*7c478bd9Sstevel@tonic-gate one_host_list(void) 436*7c478bd9Sstevel@tonic-gate { 437*7c478bd9Sstevel@tonic-gate char *key; 438*7c478bd9Sstevel@tonic-gate int keylen; 439*7c478bd9Sstevel@tonic-gate char *val; 440*7c478bd9Sstevel@tonic-gate int vallen; 441*7c478bd9Sstevel@tonic-gate int err; 442*7c478bd9Sstevel@tonic-gate char *ypservers = "ypservers"; 443*7c478bd9Sstevel@tonic-gate 444*7c478bd9Sstevel@tonic-gate if (verbose) { 445*7c478bd9Sstevel@tonic-gate printf("Verifying YP server: %s\n", host); 446*7c478bd9Sstevel@tonic-gate fflush(stdout); 447*7c478bd9Sstevel@tonic-gate } 448*7c478bd9Sstevel@tonic-gate 449*7c478bd9Sstevel@tonic-gate if (err = yp_bind(domain_alias)) { 450*7c478bd9Sstevel@tonic-gate fprintf(stderr, err_cant_bind, domain, yperr_string(err)); 451*7c478bd9Sstevel@tonic-gate exit(1); 452*7c478bd9Sstevel@tonic-gate } 453*7c478bd9Sstevel@tonic-gate 454*7c478bd9Sstevel@tonic-gate keylen = strlen(host); 455*7c478bd9Sstevel@tonic-gate 456*7c478bd9Sstevel@tonic-gate if (yp_match(domain_alias, ypservers, host, keylen, 457*7c478bd9Sstevel@tonic-gate &val, &vallen)) { 458*7c478bd9Sstevel@tonic-gate fprintf(stderr, err_cant_find_host, host); 459*7c478bd9Sstevel@tonic-gate exit(1); 460*7c478bd9Sstevel@tonic-gate } 461*7c478bd9Sstevel@tonic-gate 462*7c478bd9Sstevel@tonic-gate add_server(host, keylen); 463*7c478bd9Sstevel@tonic-gate } 464*7c478bd9Sstevel@tonic-gate 465*7c478bd9Sstevel@tonic-gate /* 466*7c478bd9Sstevel@tonic-gate * This uses yp operations to retrieve each server name in the map 467*7c478bd9Sstevel@tonic-gate * "ypservers". add_server is called for each one to add it to the list of 468*7c478bd9Sstevel@tonic-gate * servers. 469*7c478bd9Sstevel@tonic-gate */ 470*7c478bd9Sstevel@tonic-gate static void 471*7c478bd9Sstevel@tonic-gate make_server_list(void) 472*7c478bd9Sstevel@tonic-gate { 473*7c478bd9Sstevel@tonic-gate char *key; 474*7c478bd9Sstevel@tonic-gate int keylen; 475*7c478bd9Sstevel@tonic-gate char *outkey; 476*7c478bd9Sstevel@tonic-gate int outkeylen; 477*7c478bd9Sstevel@tonic-gate char *val; 478*7c478bd9Sstevel@tonic-gate int vallen; 479*7c478bd9Sstevel@tonic-gate int err; 480*7c478bd9Sstevel@tonic-gate char *ypservers = "ypservers"; 481*7c478bd9Sstevel@tonic-gate int count; 482*7c478bd9Sstevel@tonic-gate 483*7c478bd9Sstevel@tonic-gate if (verbose) { 484*7c478bd9Sstevel@tonic-gate printf("Finding YP servers: "); 485*7c478bd9Sstevel@tonic-gate fflush(stdout); 486*7c478bd9Sstevel@tonic-gate count = 4; 487*7c478bd9Sstevel@tonic-gate } 488*7c478bd9Sstevel@tonic-gate 489*7c478bd9Sstevel@tonic-gate if (err = yp_bind(domain_alias)) { 490*7c478bd9Sstevel@tonic-gate fprintf(stderr, err_cant_bind, domain, yperr_string(err)); 491*7c478bd9Sstevel@tonic-gate exit(1); 492*7c478bd9Sstevel@tonic-gate } 493*7c478bd9Sstevel@tonic-gate 494*7c478bd9Sstevel@tonic-gate if (err = yp_first(domain_alias, ypservers, &outkey, &outkeylen, 495*7c478bd9Sstevel@tonic-gate &val, &vallen)) { 496*7c478bd9Sstevel@tonic-gate fprintf(stderr, err_cant_build_serverlist, yperr_string(err)); 497*7c478bd9Sstevel@tonic-gate exit(1); 498*7c478bd9Sstevel@tonic-gate } 499*7c478bd9Sstevel@tonic-gate 500*7c478bd9Sstevel@tonic-gate for (;;) { 501*7c478bd9Sstevel@tonic-gate add_server(outkey, outkeylen); 502*7c478bd9Sstevel@tonic-gate if (verbose) { 503*7c478bd9Sstevel@tonic-gate printf(" %s", outkey); 504*7c478bd9Sstevel@tonic-gate fflush(stdout); 505*7c478bd9Sstevel@tonic-gate if (count++ == 8) { 506*7c478bd9Sstevel@tonic-gate printf("\n"); 507*7c478bd9Sstevel@tonic-gate count = 0; 508*7c478bd9Sstevel@tonic-gate } 509*7c478bd9Sstevel@tonic-gate } 510*7c478bd9Sstevel@tonic-gate free(val); 511*7c478bd9Sstevel@tonic-gate key = outkey; 512*7c478bd9Sstevel@tonic-gate keylen = outkeylen; 513*7c478bd9Sstevel@tonic-gate 514*7c478bd9Sstevel@tonic-gate if (err = yp_next(domain_alias, ypservers, key, keylen, 515*7c478bd9Sstevel@tonic-gate &outkey, &outkeylen, &val, &vallen)) { 516*7c478bd9Sstevel@tonic-gate 517*7c478bd9Sstevel@tonic-gate if (err == YPERR_NOMORE) { 518*7c478bd9Sstevel@tonic-gate break; 519*7c478bd9Sstevel@tonic-gate } else { 520*7c478bd9Sstevel@tonic-gate fprintf(stderr, err_cant_build_serverlist, 521*7c478bd9Sstevel@tonic-gate yperr_string(err)); 522*7c478bd9Sstevel@tonic-gate exit(1); 523*7c478bd9Sstevel@tonic-gate } 524*7c478bd9Sstevel@tonic-gate } 525*7c478bd9Sstevel@tonic-gate 526*7c478bd9Sstevel@tonic-gate free(key); 527*7c478bd9Sstevel@tonic-gate } 528*7c478bd9Sstevel@tonic-gate if (count != 0) { 529*7c478bd9Sstevel@tonic-gate if (verbose) 530*7c478bd9Sstevel@tonic-gate printf("\n"); 531*7c478bd9Sstevel@tonic-gate } 532*7c478bd9Sstevel@tonic-gate } 533*7c478bd9Sstevel@tonic-gate 534*7c478bd9Sstevel@tonic-gate /* 535*7c478bd9Sstevel@tonic-gate * This adds a single server to the server list. 536*7c478bd9Sstevel@tonic-gate */ 537*7c478bd9Sstevel@tonic-gate static void 538*7c478bd9Sstevel@tonic-gate add_server(char *sname, int namelen) 539*7c478bd9Sstevel@tonic-gate { 540*7c478bd9Sstevel@tonic-gate struct server *ps; 541*7c478bd9Sstevel@tonic-gate static unsigned long seq; 542*7c478bd9Sstevel@tonic-gate static unsigned long xactid = 0; 543*7c478bd9Sstevel@tonic-gate 544*7c478bd9Sstevel@tonic-gate if (strcmp(sname, my_name) == 0) 545*7c478bd9Sstevel@tonic-gate return; 546*7c478bd9Sstevel@tonic-gate 547*7c478bd9Sstevel@tonic-gate if (xactid == 0) { 548*7c478bd9Sstevel@tonic-gate xactid_seed(&xactid); 549*7c478bd9Sstevel@tonic-gate } 550*7c478bd9Sstevel@tonic-gate 551*7c478bd9Sstevel@tonic-gate if ((ps = (struct server *)malloc((unsigned)sizeof (struct server))) 552*7c478bd9Sstevel@tonic-gate == (struct server *)NULL) { 553*7c478bd9Sstevel@tonic-gate perror("yppush: malloc failure"); 554*7c478bd9Sstevel@tonic-gate exit(1); 555*7c478bd9Sstevel@tonic-gate } 556*7c478bd9Sstevel@tonic-gate 557*7c478bd9Sstevel@tonic-gate sname[namelen] = '\0'; 558*7c478bd9Sstevel@tonic-gate strcpy(ps->svc_name, sname); 559*7c478bd9Sstevel@tonic-gate ps->state = SSTAT_INIT; 560*7c478bd9Sstevel@tonic-gate ps->status = 0; 561*7c478bd9Sstevel@tonic-gate ps->oldvers = FALSE; 562*7c478bd9Sstevel@tonic-gate ps->xactid = xactid + seq++; 563*7c478bd9Sstevel@tonic-gate ps->pnext = server_list; 564*7c478bd9Sstevel@tonic-gate server_list = ps; 565*7c478bd9Sstevel@tonic-gate } 566*7c478bd9Sstevel@tonic-gate 567*7c478bd9Sstevel@tonic-gate /* 568*7c478bd9Sstevel@tonic-gate * This sets the base range for the transaction ids used in speaking the the 569*7c478bd9Sstevel@tonic-gate * server ypxfr processes. 570*7c478bd9Sstevel@tonic-gate */ 571*7c478bd9Sstevel@tonic-gate static void 572*7c478bd9Sstevel@tonic-gate xactid_seed(unsigned long *xactid) 573*7c478bd9Sstevel@tonic-gate { 574*7c478bd9Sstevel@tonic-gate struct timeval t; 575*7c478bd9Sstevel@tonic-gate 576*7c478bd9Sstevel@tonic-gate if (gettimeofday(&t) == -1) { 577*7c478bd9Sstevel@tonic-gate perror("yppush gettimeofday failure"); 578*7c478bd9Sstevel@tonic-gate *xactid = 1234567; 579*7c478bd9Sstevel@tonic-gate } else { 580*7c478bd9Sstevel@tonic-gate *xactid = t.tv_sec; 581*7c478bd9Sstevel@tonic-gate } 582*7c478bd9Sstevel@tonic-gate } 583*7c478bd9Sstevel@tonic-gate 584*7c478bd9Sstevel@tonic-gate /* 585*7c478bd9Sstevel@tonic-gate * This generates the channel which will be used as the listener process' 586*7c478bd9Sstevel@tonic-gate * service rendezvous point, and comes up with a transient program number 587*7c478bd9Sstevel@tonic-gate * for the use of the RPC messages from the ypxfr processes. 588*7c478bd9Sstevel@tonic-gate */ 589*7c478bd9Sstevel@tonic-gate static int 590*7c478bd9Sstevel@tonic-gate generate_callback(unsigned long *program) 591*7c478bd9Sstevel@tonic-gate { 592*7c478bd9Sstevel@tonic-gate unsigned long prognum = 0x40000000, maxprognum; 593*7c478bd9Sstevel@tonic-gate union { 594*7c478bd9Sstevel@tonic-gate unsigned long p; 595*7c478bd9Sstevel@tonic-gate unsigned char b[sizeof (unsigned long)]; 596*7c478bd9Sstevel@tonic-gate } u; 597*7c478bd9Sstevel@tonic-gate int ret, i; 598*7c478bd9Sstevel@tonic-gate struct netconfig *nc4, *nc6, *nc; 599*7c478bd9Sstevel@tonic-gate SVCXPRT *trans; 600*7c478bd9Sstevel@tonic-gate 601*7c478bd9Sstevel@tonic-gate nc4 = getnetconfigent("udp"); 602*7c478bd9Sstevel@tonic-gate nc6 = getnetconfigent("udp6"); 603*7c478bd9Sstevel@tonic-gate if (nc4 == 0 && nc6 == 0) { 604*7c478bd9Sstevel@tonic-gate fprintf(stderr, 605*7c478bd9Sstevel@tonic-gate "yppush: Could not get udp or udp6 netconfig entry\n"); 606*7c478bd9Sstevel@tonic-gate exit(1); 607*7c478bd9Sstevel@tonic-gate } 608*7c478bd9Sstevel@tonic-gate 609*7c478bd9Sstevel@tonic-gate transport4 = (nc4 == 0) ? 0 : svc_tli_create(RPC_ANYFD, nc4, 0, 0, 0); 610*7c478bd9Sstevel@tonic-gate transport6 = (nc6 == 0) ? 0 : svc_tli_create(RPC_ANYFD, nc6, 0, 0, 0); 611*7c478bd9Sstevel@tonic-gate if (transport4 == 0 && transport6 == 0) { 612*7c478bd9Sstevel@tonic-gate fprintf(stderr, "yppush: Could not create server handle(s)\n"); 613*7c478bd9Sstevel@tonic-gate exit(1); 614*7c478bd9Sstevel@tonic-gate } 615*7c478bd9Sstevel@tonic-gate 616*7c478bd9Sstevel@tonic-gate /* Find the maximum possible program number using an unsigned long */ 617*7c478bd9Sstevel@tonic-gate for (i = 0; i < sizeof (u.b); i++) 618*7c478bd9Sstevel@tonic-gate u.b[i] = 0xff; 619*7c478bd9Sstevel@tonic-gate maxprognum = u.p; 620*7c478bd9Sstevel@tonic-gate 621*7c478bd9Sstevel@tonic-gate if (transport4 != 0) { 622*7c478bd9Sstevel@tonic-gate trans = transport4; 623*7c478bd9Sstevel@tonic-gate nc = nc4; 624*7c478bd9Sstevel@tonic-gate } else { 625*7c478bd9Sstevel@tonic-gate trans = transport6; 626*7c478bd9Sstevel@tonic-gate nc = nc6; 627*7c478bd9Sstevel@tonic-gate } 628*7c478bd9Sstevel@tonic-gate while (prognum < maxprognum && (ret = 629*7c478bd9Sstevel@tonic-gate rpcb_set(prognum, YPPUSHVERS, nc, &trans->xp_ltaddr)) == 0) 630*7c478bd9Sstevel@tonic-gate prognum++; 631*7c478bd9Sstevel@tonic-gate 632*7c478bd9Sstevel@tonic-gate if (ret == 0) { 633*7c478bd9Sstevel@tonic-gate fprintf(stderr, "yppush: Could not create callback service\n"); 634*7c478bd9Sstevel@tonic-gate exit(1); 635*7c478bd9Sstevel@tonic-gate } else { 636*7c478bd9Sstevel@tonic-gate if (trans == transport4 && transport6 != 0) { 637*7c478bd9Sstevel@tonic-gate ret = rpcb_set(prognum, YPPUSHVERS, nc6, 638*7c478bd9Sstevel@tonic-gate &transport6->xp_ltaddr); 639*7c478bd9Sstevel@tonic-gate if (ret == 0) { 640*7c478bd9Sstevel@tonic-gate fprintf(stderr, 641*7c478bd9Sstevel@tonic-gate "yppush: Could not create udp6 callback service\n"); 642*7c478bd9Sstevel@tonic-gate exit(1); 643*7c478bd9Sstevel@tonic-gate } 644*7c478bd9Sstevel@tonic-gate } 645*7c478bd9Sstevel@tonic-gate *program = prognum; 646*7c478bd9Sstevel@tonic-gate } 647*7c478bd9Sstevel@tonic-gate 648*7c478bd9Sstevel@tonic-gate return (ret); 649*7c478bd9Sstevel@tonic-gate } 650*7c478bd9Sstevel@tonic-gate 651*7c478bd9Sstevel@tonic-gate /* 652*7c478bd9Sstevel@tonic-gate * This is the main loop. Send messages to each server, 653*7c478bd9Sstevel@tonic-gate * and then wait for a response. 654*7c478bd9Sstevel@tonic-gate */ 655*7c478bd9Sstevel@tonic-gate 656*7c478bd9Sstevel@tonic-gate 657*7c478bd9Sstevel@tonic-gate add_to_active() 658*7c478bd9Sstevel@tonic-gate { 659*7c478bd9Sstevel@tonic-gate struct server *ps; 660*7c478bd9Sstevel@tonic-gate ps = server_list; 661*7c478bd9Sstevel@tonic-gate if (ps == NULL) 662*7c478bd9Sstevel@tonic-gate return (0); 663*7c478bd9Sstevel@tonic-gate server_list = server_list->pnext; /* delete from server_list */ 664*7c478bd9Sstevel@tonic-gate ps->pnext = active_list; 665*7c478bd9Sstevel@tonic-gate active_list = ps; 666*7c478bd9Sstevel@tonic-gate return (1); 667*7c478bd9Sstevel@tonic-gate } 668*7c478bd9Sstevel@tonic-gate 669*7c478bd9Sstevel@tonic-gate delete_active(in) 670*7c478bd9Sstevel@tonic-gate struct server *in; 671*7c478bd9Sstevel@tonic-gate { 672*7c478bd9Sstevel@tonic-gate struct server *p; 673*7c478bd9Sstevel@tonic-gate struct server *n; 674*7c478bd9Sstevel@tonic-gate if (in == active_list) { 675*7c478bd9Sstevel@tonic-gate active_list = active_list->pnext; 676*7c478bd9Sstevel@tonic-gate return (1); 677*7c478bd9Sstevel@tonic-gate } 678*7c478bd9Sstevel@tonic-gate p = active_list; 679*7c478bd9Sstevel@tonic-gate for (n = active_list; n; n = n->pnext) { 680*7c478bd9Sstevel@tonic-gate if (in == n) { 681*7c478bd9Sstevel@tonic-gate p->pnext = n->pnext; 682*7c478bd9Sstevel@tonic-gate return (0); 683*7c478bd9Sstevel@tonic-gate 684*7c478bd9Sstevel@tonic-gate } 685*7c478bd9Sstevel@tonic-gate p = n; 686*7c478bd9Sstevel@tonic-gate } 687*7c478bd9Sstevel@tonic-gate return (-1); 688*7c478bd9Sstevel@tonic-gate } 689*7c478bd9Sstevel@tonic-gate 690*7c478bd9Sstevel@tonic-gate void 691*7c478bd9Sstevel@tonic-gate main_loop(program) 692*7c478bd9Sstevel@tonic-gate unsigned long program; 693*7c478bd9Sstevel@tonic-gate { 694*7c478bd9Sstevel@tonic-gate pollfd_t *pollset = NULL; 695*7c478bd9Sstevel@tonic-gate int npollfds = 0; 696*7c478bd9Sstevel@tonic-gate int pollret; 697*7c478bd9Sstevel@tonic-gate struct server *ps; 698*7c478bd9Sstevel@tonic-gate long error; 699*7c478bd9Sstevel@tonic-gate int hpar; /* this times par count */ 700*7c478bd9Sstevel@tonic-gate int i; 701*7c478bd9Sstevel@tonic-gate int j; 702*7c478bd9Sstevel@tonic-gate int time_now; 703*7c478bd9Sstevel@tonic-gate int docb; 704*7c478bd9Sstevel@tonic-gate int actives = 0; 705*7c478bd9Sstevel@tonic-gate int dead = 0; 706*7c478bd9Sstevel@tonic-gate 707*7c478bd9Sstevel@tonic-gate if (grace_period < MIN_GRACE) 708*7c478bd9Sstevel@tonic-gate grace_period = MIN_GRACE; 709*7c478bd9Sstevel@tonic-gate if (transport4 != 0) { 710*7c478bd9Sstevel@tonic-gate if (!svc_reg(transport4, program, YPPUSHVERS, 711*7c478bd9Sstevel@tonic-gate listener_dispatch, 0)) { 712*7c478bd9Sstevel@tonic-gate fprintf(stderr, 713*7c478bd9Sstevel@tonic-gate "Can't set up transient udp callback server.\n"); 714*7c478bd9Sstevel@tonic-gate } 715*7c478bd9Sstevel@tonic-gate } 716*7c478bd9Sstevel@tonic-gate if (transport6 != 0) { 717*7c478bd9Sstevel@tonic-gate if (!svc_reg(transport6, program, YPPUSHVERS, 718*7c478bd9Sstevel@tonic-gate listener_dispatch, 0)) { 719*7c478bd9Sstevel@tonic-gate fprintf(stderr, 720*7c478bd9Sstevel@tonic-gate "Can't set up transient udp6 callback server.\n"); 721*7c478bd9Sstevel@tonic-gate } 722*7c478bd9Sstevel@tonic-gate } 723*7c478bd9Sstevel@tonic-gate for (;;) { 724*7c478bd9Sstevel@tonic-gate time_now = time(0); 725*7c478bd9Sstevel@tonic-gate if (server_list == NULL) { 726*7c478bd9Sstevel@tonic-gate actives = 0; 727*7c478bd9Sstevel@tonic-gate dead = 0; 728*7c478bd9Sstevel@tonic-gate for (ps = active_list; ps; ps = ps->pnext) 729*7c478bd9Sstevel@tonic-gate if (ps->state == SSTAT_CALLED) { 730*7c478bd9Sstevel@tonic-gate if ((time_now - ps->start_time) < 731*7c478bd9Sstevel@tonic-gate grace_period) 732*7c478bd9Sstevel@tonic-gate actives++; 733*7c478bd9Sstevel@tonic-gate else 734*7c478bd9Sstevel@tonic-gate dead++; 735*7c478bd9Sstevel@tonic-gate } 736*7c478bd9Sstevel@tonic-gate if (actives == 0) { 737*7c478bd9Sstevel@tonic-gate if (verbose) { 738*7c478bd9Sstevel@tonic-gate printf("terminating %d dead\n", dead); 739*7c478bd9Sstevel@tonic-gate fflush(stdout); 740*7c478bd9Sstevel@tonic-gate } 741*7c478bd9Sstevel@tonic-gate 742*7c478bd9Sstevel@tonic-gate for (ps = active_list; ps; ps = ps->pnext) 743*7c478bd9Sstevel@tonic-gate if (ps->state == SSTAT_CALLED) { 744*7c478bd9Sstevel@tonic-gate if ((time_now - ps->start_time) 745*7c478bd9Sstevel@tonic-gate >= grace_period) { 746*7c478bd9Sstevel@tonic-gate if (verbose) { 747*7c478bd9Sstevel@tonic-gate printf( 748*7c478bd9Sstevel@tonic-gate "no response from %s -- grace of %d seconds expired.\n", 749*7c478bd9Sstevel@tonic-gate ps->svc_name, grace_period); 750*7c478bd9Sstevel@tonic-gate fflush(stdout); 751*7c478bd9Sstevel@tonic-gate } 752*7c478bd9Sstevel@tonic-gate fprintf(stderr, 753*7c478bd9Sstevel@tonic-gate "No response from ypxfr on %s\n", ps->svc_name); 754*7c478bd9Sstevel@tonic-gate } 755*7c478bd9Sstevel@tonic-gate } 756*7c478bd9Sstevel@tonic-gate break; 757*7c478bd9Sstevel@tonic-gate } 758*7c478bd9Sstevel@tonic-gate } 759*7c478bd9Sstevel@tonic-gate actives = 0; 760*7c478bd9Sstevel@tonic-gate for (ps = active_list; ps; ps = ps->pnext) { 761*7c478bd9Sstevel@tonic-gate if (ps->state == SSTAT_CALLED) { 762*7c478bd9Sstevel@tonic-gate if ((time_now - ps->start_time) 763*7c478bd9Sstevel@tonic-gate < grace_period) { 764*7c478bd9Sstevel@tonic-gate actives++; 765*7c478bd9Sstevel@tonic-gate 766*7c478bd9Sstevel@tonic-gate if (verbose) { 767*7c478bd9Sstevel@tonic-gate printf( 768*7c478bd9Sstevel@tonic-gate "No response yet from ypxfr on %s\n", ps->svc_name); 769*7c478bd9Sstevel@tonic-gate fflush(stdout); 770*7c478bd9Sstevel@tonic-gate } 771*7c478bd9Sstevel@tonic-gate } 772*7c478bd9Sstevel@tonic-gate } else { 773*7c478bd9Sstevel@tonic-gate if (verbose) { 774*7c478bd9Sstevel@tonic-gate printf("Deactivating %s\n", 775*7c478bd9Sstevel@tonic-gate ps->svc_name); 776*7c478bd9Sstevel@tonic-gate fflush(stdout); 777*7c478bd9Sstevel@tonic-gate } 778*7c478bd9Sstevel@tonic-gate delete_active(ps); 779*7c478bd9Sstevel@tonic-gate } 780*7c478bd9Sstevel@tonic-gate } 781*7c478bd9Sstevel@tonic-gate 782*7c478bd9Sstevel@tonic-gate /* add someone to the active list keep up with curpar */ 783*7c478bd9Sstevel@tonic-gate for (i = 0; i < (curpar - actives); i++) { 784*7c478bd9Sstevel@tonic-gate if (add_to_active()) { 785*7c478bd9Sstevel@tonic-gate ps = active_list; 786*7c478bd9Sstevel@tonic-gate ps->state = send_message(ps, program, &error); 787*7c478bd9Sstevel@tonic-gate print_state_msg(ps, error); 788*7c478bd9Sstevel@tonic-gate if (ps->state != SSTAT_CALLED) 789*7c478bd9Sstevel@tonic-gate delete_active(ps); /* zorch it */ 790*7c478bd9Sstevel@tonic-gate else 791*7c478bd9Sstevel@tonic-gate ps->start_time = time(0); /* set time */ 792*7c478bd9Sstevel@tonic-gate } 793*7c478bd9Sstevel@tonic-gate } 794*7c478bd9Sstevel@tonic-gate docb = 0; 795*7c478bd9Sstevel@tonic-gate for (ps = active_list; ps; ps = ps->pnext) 796*7c478bd9Sstevel@tonic-gate if (ps->state == SSTAT_CALLED) { 797*7c478bd9Sstevel@tonic-gate docb = 1; 798*7c478bd9Sstevel@tonic-gate break; 799*7c478bd9Sstevel@tonic-gate } 800*7c478bd9Sstevel@tonic-gate if (docb == 0) { 801*7c478bd9Sstevel@tonic-gate if (verbose) { 802*7c478bd9Sstevel@tonic-gate printf("No one to wait for this pass.\n"); 803*7c478bd9Sstevel@tonic-gate fflush(stdout); 804*7c478bd9Sstevel@tonic-gate } 805*7c478bd9Sstevel@tonic-gate continue; /* try curpar more */ 806*7c478bd9Sstevel@tonic-gate } 807*7c478bd9Sstevel@tonic-gate 808*7c478bd9Sstevel@tonic-gate if (npollfds != svc_max_pollfd) { 809*7c478bd9Sstevel@tonic-gate pollset = realloc(pollset, 810*7c478bd9Sstevel@tonic-gate sizeof (pollfd_t) * svc_max_pollfd); 811*7c478bd9Sstevel@tonic-gate npollfds = svc_max_pollfd; 812*7c478bd9Sstevel@tonic-gate } 813*7c478bd9Sstevel@tonic-gate 814*7c478bd9Sstevel@tonic-gate /* 815*7c478bd9Sstevel@tonic-gate * Get existing array of pollfd's, should really compress 816*7c478bd9Sstevel@tonic-gate * this but it shouldn't get very large (or sparse). 817*7c478bd9Sstevel@tonic-gate */ 818*7c478bd9Sstevel@tonic-gate (void) memcpy(pollset, svc_pollfd, 819*7c478bd9Sstevel@tonic-gate sizeof (pollfd_t) * svc_max_pollfd); 820*7c478bd9Sstevel@tonic-gate 821*7c478bd9Sstevel@tonic-gate errno = 0; 822*7c478bd9Sstevel@tonic-gate switch (pollret = poll(pollset, npollfds, MIN_GRACE * 1000)) { 823*7c478bd9Sstevel@tonic-gate case -1: 824*7c478bd9Sstevel@tonic-gate if (errno != EINTR) { 825*7c478bd9Sstevel@tonic-gate (void) perror("main loop select"); 826*7c478bd9Sstevel@tonic-gate } 827*7c478bd9Sstevel@tonic-gate break; 828*7c478bd9Sstevel@tonic-gate 829*7c478bd9Sstevel@tonic-gate case 0: 830*7c478bd9Sstevel@tonic-gate if (verbose) { 831*7c478bd9Sstevel@tonic-gate (void) printf("timeout in main loop select.\n"); 832*7c478bd9Sstevel@tonic-gate fflush(stdout); 833*7c478bd9Sstevel@tonic-gate } 834*7c478bd9Sstevel@tonic-gate break; 835*7c478bd9Sstevel@tonic-gate 836*7c478bd9Sstevel@tonic-gate default: 837*7c478bd9Sstevel@tonic-gate svc_getreq_poll(pollset, pollret); 838*7c478bd9Sstevel@tonic-gate break; 839*7c478bd9Sstevel@tonic-gate } /* switch */ 840*7c478bd9Sstevel@tonic-gate } /* for */ 841*7c478bd9Sstevel@tonic-gate } 842*7c478bd9Sstevel@tonic-gate 843*7c478bd9Sstevel@tonic-gate /* 844*7c478bd9Sstevel@tonic-gate * This does the listener process cleanup and process exit. 845*7c478bd9Sstevel@tonic-gate */ 846*7c478bd9Sstevel@tonic-gate static void 847*7c478bd9Sstevel@tonic-gate listener_exit(unsigned long program, int stat) 848*7c478bd9Sstevel@tonic-gate { 849*7c478bd9Sstevel@tonic-gate svc_unreg(program, YPPUSHVERS); 850*7c478bd9Sstevel@tonic-gate exit(stat); 851*7c478bd9Sstevel@tonic-gate } 852*7c478bd9Sstevel@tonic-gate 853*7c478bd9Sstevel@tonic-gate /* 854*7c478bd9Sstevel@tonic-gate * This is the listener process' RPC service dispatcher. 855*7c478bd9Sstevel@tonic-gate */ 856*7c478bd9Sstevel@tonic-gate static void 857*7c478bd9Sstevel@tonic-gate listener_dispatch(struct svc_req *rqstp, SVCXPRT *transp) 858*7c478bd9Sstevel@tonic-gate { 859*7c478bd9Sstevel@tonic-gate switch (rqstp->rq_proc) { 860*7c478bd9Sstevel@tonic-gate 861*7c478bd9Sstevel@tonic-gate case YPPUSHPROC_NULL: 862*7c478bd9Sstevel@tonic-gate if (!svc_sendreply(transp, xdr_void, 0)) { 863*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Can't reply to rpc call.\n"); 864*7c478bd9Sstevel@tonic-gate } 865*7c478bd9Sstevel@tonic-gate break; 866*7c478bd9Sstevel@tonic-gate 867*7c478bd9Sstevel@tonic-gate case YPPUSHPROC_XFRRESP: 868*7c478bd9Sstevel@tonic-gate get_xfr_response(transp); 869*7c478bd9Sstevel@tonic-gate break; 870*7c478bd9Sstevel@tonic-gate 871*7c478bd9Sstevel@tonic-gate default: 872*7c478bd9Sstevel@tonic-gate svcerr_noproc(transp); 873*7c478bd9Sstevel@tonic-gate break; 874*7c478bd9Sstevel@tonic-gate } 875*7c478bd9Sstevel@tonic-gate } 876*7c478bd9Sstevel@tonic-gate 877*7c478bd9Sstevel@tonic-gate 878*7c478bd9Sstevel@tonic-gate /* 879*7c478bd9Sstevel@tonic-gate * This dumps a server state message to stdout. It is called in cases where 880*7c478bd9Sstevel@tonic-gate * we have no expectation of receiving a callback from the remote ypxfr. 881*7c478bd9Sstevel@tonic-gate */ 882*7c478bd9Sstevel@tonic-gate static void 883*7c478bd9Sstevel@tonic-gate print_state_msg(struct server *s, long e) 884*7c478bd9Sstevel@tonic-gate { 885*7c478bd9Sstevel@tonic-gate struct state_duple *sd; 886*7c478bd9Sstevel@tonic-gate 887*7c478bd9Sstevel@tonic-gate if (s->state == SSTAT_SYSTEM) 888*7c478bd9Sstevel@tonic-gate return; /* already printed */ 889*7c478bd9Sstevel@tonic-gate 890*7c478bd9Sstevel@tonic-gate if (!verbose && (s->state == SSTAT_RESPONDED || 891*7c478bd9Sstevel@tonic-gate s->state == SSTAT_CALLED)) 892*7c478bd9Sstevel@tonic-gate return; 893*7c478bd9Sstevel@tonic-gate 894*7c478bd9Sstevel@tonic-gate for (sd = state_duples; sd->state_msg; sd++) { 895*7c478bd9Sstevel@tonic-gate if (sd->state == s->state) { 896*7c478bd9Sstevel@tonic-gate printf(sd->state_msg, s->svc_name); 897*7c478bd9Sstevel@tonic-gate 898*7c478bd9Sstevel@tonic-gate if (s->state == SSTAT_RPC) { 899*7c478bd9Sstevel@tonic-gate rpcerr_msg((enum clnt_stat) e); 900*7c478bd9Sstevel@tonic-gate } 901*7c478bd9Sstevel@tonic-gate 902*7c478bd9Sstevel@tonic-gate printf("\n"); 903*7c478bd9Sstevel@tonic-gate fflush(stdout); 904*7c478bd9Sstevel@tonic-gate return; 905*7c478bd9Sstevel@tonic-gate } 906*7c478bd9Sstevel@tonic-gate } 907*7c478bd9Sstevel@tonic-gate 908*7c478bd9Sstevel@tonic-gate fprintf(stderr, "yppush: Bad server state value %d.\n", s->state); 909*7c478bd9Sstevel@tonic-gate } 910*7c478bd9Sstevel@tonic-gate 911*7c478bd9Sstevel@tonic-gate /* 912*7c478bd9Sstevel@tonic-gate * This dumps a transfer status message to stdout. It is called in 913*7c478bd9Sstevel@tonic-gate * response to a received RPC message from the called ypxfr. 914*7c478bd9Sstevel@tonic-gate */ 915*7c478bd9Sstevel@tonic-gate static void 916*7c478bd9Sstevel@tonic-gate print_callback_msg(struct server *s) 917*7c478bd9Sstevel@tonic-gate { 918*7c478bd9Sstevel@tonic-gate register struct status_duple *sd; 919*7c478bd9Sstevel@tonic-gate 920*7c478bd9Sstevel@tonic-gate if (!verbose && 921*7c478bd9Sstevel@tonic-gate (s->status == YPPUSH_AGE) || 922*7c478bd9Sstevel@tonic-gate (s->status == YPPUSH_SUCC)) 923*7c478bd9Sstevel@tonic-gate 924*7c478bd9Sstevel@tonic-gate return; 925*7c478bd9Sstevel@tonic-gate 926*7c478bd9Sstevel@tonic-gate for (sd = status_duples; sd->status_msg; sd++) { 927*7c478bd9Sstevel@tonic-gate 928*7c478bd9Sstevel@tonic-gate if (sd->status == s->status) { 929*7c478bd9Sstevel@tonic-gate printf("Status received from ypxfr on %s:\n\t%s\n", 930*7c478bd9Sstevel@tonic-gate s->svc_name, sd->status_msg); 931*7c478bd9Sstevel@tonic-gate fflush(stdout); 932*7c478bd9Sstevel@tonic-gate return; 933*7c478bd9Sstevel@tonic-gate } 934*7c478bd9Sstevel@tonic-gate } 935*7c478bd9Sstevel@tonic-gate 936*7c478bd9Sstevel@tonic-gate fprintf(stderr, "yppush listener: Garbage transaction " 937*7c478bd9Sstevel@tonic-gate "status (value %d) from ypxfr on %s.\n", 938*7c478bd9Sstevel@tonic-gate (int)s->status, s->svc_name); 939*7c478bd9Sstevel@tonic-gate } 940*7c478bd9Sstevel@tonic-gate 941*7c478bd9Sstevel@tonic-gate /* 942*7c478bd9Sstevel@tonic-gate * This dumps an RPC error message to stdout. This is basically a rewrite 943*7c478bd9Sstevel@tonic-gate * of clnt_perrno, but writes to stdout instead of stderr. 944*7c478bd9Sstevel@tonic-gate */ 945*7c478bd9Sstevel@tonic-gate static void 946*7c478bd9Sstevel@tonic-gate rpcerr_msg(enum clnt_stat e) 947*7c478bd9Sstevel@tonic-gate { 948*7c478bd9Sstevel@tonic-gate struct rpcerr_duple *rd; 949*7c478bd9Sstevel@tonic-gate 950*7c478bd9Sstevel@tonic-gate for (rd = rpcerr_duples; rd->rpc_msg; rd++) { 951*7c478bd9Sstevel@tonic-gate 952*7c478bd9Sstevel@tonic-gate if (rd->rpc_stat == e) { 953*7c478bd9Sstevel@tonic-gate printf(rd->rpc_msg); 954*7c478bd9Sstevel@tonic-gate return; 955*7c478bd9Sstevel@tonic-gate } 956*7c478bd9Sstevel@tonic-gate } 957*7c478bd9Sstevel@tonic-gate 958*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Bad error code passed to rpcerr_msg: %d.\n", e); 959*7c478bd9Sstevel@tonic-gate } 960*7c478bd9Sstevel@tonic-gate 961*7c478bd9Sstevel@tonic-gate /* 962*7c478bd9Sstevel@tonic-gate * This picks up the response from the ypxfr process which has been started 963*7c478bd9Sstevel@tonic-gate * up on the remote node. The response status must be non-zero, otherwise 964*7c478bd9Sstevel@tonic-gate * the status will be set to "ypxfr error". 965*7c478bd9Sstevel@tonic-gate */ 966*7c478bd9Sstevel@tonic-gate static void 967*7c478bd9Sstevel@tonic-gate get_xfr_response(SVCXPRT *transp) 968*7c478bd9Sstevel@tonic-gate { 969*7c478bd9Sstevel@tonic-gate struct yppushresp_xfr resp; 970*7c478bd9Sstevel@tonic-gate register struct server *s; 971*7c478bd9Sstevel@tonic-gate 972*7c478bd9Sstevel@tonic-gate if (!svc_getargs(transp, (xdrproc_t)xdr_yppushresp_xfr, 973*7c478bd9Sstevel@tonic-gate (caddr_t)&resp)) { 974*7c478bd9Sstevel@tonic-gate svcerr_decode(transp); 975*7c478bd9Sstevel@tonic-gate return; 976*7c478bd9Sstevel@tonic-gate } 977*7c478bd9Sstevel@tonic-gate 978*7c478bd9Sstevel@tonic-gate if (!svc_sendreply(transp, xdr_void, 0)) { 979*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Can't reply to rpc call.\n"); 980*7c478bd9Sstevel@tonic-gate } 981*7c478bd9Sstevel@tonic-gate 982*7c478bd9Sstevel@tonic-gate for (s = active_list; s; s = s->pnext) { 983*7c478bd9Sstevel@tonic-gate 984*7c478bd9Sstevel@tonic-gate if (s->xactid == resp.transid) { 985*7c478bd9Sstevel@tonic-gate s->status = resp.status ? resp.status: YPPUSH_XFRERR; 986*7c478bd9Sstevel@tonic-gate print_callback_msg(s); 987*7c478bd9Sstevel@tonic-gate s->state = SSTAT_RESPONDED; 988*7c478bd9Sstevel@tonic-gate return; 989*7c478bd9Sstevel@tonic-gate } 990*7c478bd9Sstevel@tonic-gate } 991*7c478bd9Sstevel@tonic-gate } 992*7c478bd9Sstevel@tonic-gate 993*7c478bd9Sstevel@tonic-gate /* 994*7c478bd9Sstevel@tonic-gate * This sends a message to a single ypserv process. The return value is 995*7c478bd9Sstevel@tonic-gate * a state value. If the RPC call fails because of a version 996*7c478bd9Sstevel@tonic-gate * mismatch, we'll assume that we're talking to a version 1 ypserv process, 997*7c478bd9Sstevel@tonic-gate * and will send him an old "YPPROC_GET" request, as was defined in the 998*7c478bd9Sstevel@tonic-gate * earlier version of yp_prot.h 999*7c478bd9Sstevel@tonic-gate */ 1000*7c478bd9Sstevel@tonic-gate static unsigned short 1001*7c478bd9Sstevel@tonic-gate send_message(struct server *ps, unsigned long program, long *err) 1002*7c478bd9Sstevel@tonic-gate { 1003*7c478bd9Sstevel@tonic-gate struct ypreq_newxfr req; 1004*7c478bd9Sstevel@tonic-gate struct ypreq_xfr oldreq; 1005*7c478bd9Sstevel@tonic-gate enum clnt_stat s; 1006*7c478bd9Sstevel@tonic-gate struct rpc_err rpcerr; 1007*7c478bd9Sstevel@tonic-gate 1008*7c478bd9Sstevel@tonic-gate if ((ps->domb.dom_client = __yp_clnt_create_rsvdport(ps->svc_name, 1009*7c478bd9Sstevel@tonic-gate YPPROG, YPVERS, 1010*7c478bd9Sstevel@tonic-gate (char *)NULL, 1011*7c478bd9Sstevel@tonic-gate 0, 0)) == NULL) { 1012*7c478bd9Sstevel@tonic-gate 1013*7c478bd9Sstevel@tonic-gate if (rpc_createerr.cf_stat == RPC_PROGNOTREGISTERED) { 1014*7c478bd9Sstevel@tonic-gate return (SSTAT_PROGNOTREG); 1015*7c478bd9Sstevel@tonic-gate } else { 1016*7c478bd9Sstevel@tonic-gate printf("Error talking to %s: ", ps->svc_name); 1017*7c478bd9Sstevel@tonic-gate rpcerr_msg(rpc_createerr.cf_stat); 1018*7c478bd9Sstevel@tonic-gate printf("\n"); 1019*7c478bd9Sstevel@tonic-gate fflush(stdout); 1020*7c478bd9Sstevel@tonic-gate return (SSTAT_SYSTEM); 1021*7c478bd9Sstevel@tonic-gate } 1022*7c478bd9Sstevel@tonic-gate } 1023*7c478bd9Sstevel@tonic-gate 1024*7c478bd9Sstevel@tonic-gate if (sysinfo(SI_HOSTNAME, my_name, sizeof (my_name)) == -1) { 1025*7c478bd9Sstevel@tonic-gate return (SSTAT_RSCRC); 1026*7c478bd9Sstevel@tonic-gate } 1027*7c478bd9Sstevel@tonic-gate 1028*7c478bd9Sstevel@tonic-gate if (!oldxfr) { 1029*7c478bd9Sstevel@tonic-gate req.ypxfr_domain = domain; 1030*7c478bd9Sstevel@tonic-gate req.ypxfr_map = map; 1031*7c478bd9Sstevel@tonic-gate req.ypxfr_ordernum = 0; 1032*7c478bd9Sstevel@tonic-gate req.ypxfr_owner = my_name; 1033*7c478bd9Sstevel@tonic-gate req.name = ps->svc_name; 1034*7c478bd9Sstevel@tonic-gate /* 1035*7c478bd9Sstevel@tonic-gate * the creation of field req.name, instead of ypreq_xfr (old) 1036*7c478bd9Sstevel@tonic-gate * req.port, does not make any sense. it doesn't give any 1037*7c478bd9Sstevel@tonic-gate * information to receiving ypserv except its own name !! 1038*7c478bd9Sstevel@tonic-gate * new ypserv duplicates work for YPPROC_XFR and YPPROC_NEWXFR 1039*7c478bd9Sstevel@tonic-gate */ 1040*7c478bd9Sstevel@tonic-gate req.transid = ps->xactid; 1041*7c478bd9Sstevel@tonic-gate req.proto = program; 1042*7c478bd9Sstevel@tonic-gate s = (enum clnt_stat) clnt_call(ps->domb.dom_client, 1043*7c478bd9Sstevel@tonic-gate YPPROC_NEWXFR, 1044*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_ypreq_newxfr, 1045*7c478bd9Sstevel@tonic-gate (caddr_t)&req, 1046*7c478bd9Sstevel@tonic-gate xdr_void, 0, timeout); 1047*7c478bd9Sstevel@tonic-gate } 1048*7c478bd9Sstevel@tonic-gate 1049*7c478bd9Sstevel@tonic-gate clnt_geterr(ps->domb.dom_client, &rpcerr); 1050*7c478bd9Sstevel@tonic-gate 1051*7c478bd9Sstevel@tonic-gate if (s == RPC_PROCUNAVAIL) { 1052*7c478bd9Sstevel@tonic-gate oldreq.ypxfr_domain = domain; 1053*7c478bd9Sstevel@tonic-gate oldreq.ypxfr_map = map; 1054*7c478bd9Sstevel@tonic-gate oldreq.ypxfr_ordernum = 0; 1055*7c478bd9Sstevel@tonic-gate oldreq.ypxfr_owner = my_name; 1056*7c478bd9Sstevel@tonic-gate oldreq.transid = ps->xactid; 1057*7c478bd9Sstevel@tonic-gate oldreq.proto = program; 1058*7c478bd9Sstevel@tonic-gate oldreq.port = 0; 1059*7c478bd9Sstevel@tonic-gate s = (enum clnt_stat) clnt_call(ps->domb.dom_client, 1060*7c478bd9Sstevel@tonic-gate YPPROC_XFR, 1061*7c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_ypreq_xfr, 1062*7c478bd9Sstevel@tonic-gate (caddr_t)&oldreq, 1063*7c478bd9Sstevel@tonic-gate xdr_void, 0, timeout); 1064*7c478bd9Sstevel@tonic-gate clnt_geterr(ps->domb.dom_client, &rpcerr); 1065*7c478bd9Sstevel@tonic-gate } 1066*7c478bd9Sstevel@tonic-gate 1067*7c478bd9Sstevel@tonic-gate clnt_destroy(ps->domb.dom_client); 1068*7c478bd9Sstevel@tonic-gate 1069*7c478bd9Sstevel@tonic-gate if (s == RPC_SUCCESS) { 1070*7c478bd9Sstevel@tonic-gate return (SSTAT_CALLED); 1071*7c478bd9Sstevel@tonic-gate } else { 1072*7c478bd9Sstevel@tonic-gate *err = (long)rpcerr.re_status; 1073*7c478bd9Sstevel@tonic-gate return (SSTAT_RPC); 1074*7c478bd9Sstevel@tonic-gate } 1075*7c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 1076*7c478bd9Sstevel@tonic-gate } 1077*7c478bd9Sstevel@tonic-gate 1078*7c478bd9Sstevel@tonic-gate /* 1079*7c478bd9Sstevel@tonic-gate * FUNCTION: is_yptol_mode(); 1080*7c478bd9Sstevel@tonic-gate * 1081*7c478bd9Sstevel@tonic-gate * DESCRIPTION: Determines if we should run in N2L or traditional mode based 1082*7c478bd9Sstevel@tonic-gate * on the presence of the N2L mapping file. 1083*7c478bd9Sstevel@tonic-gate * 1084*7c478bd9Sstevel@tonic-gate * This is a copy of a function from libnisdb. If more than this 1085*7c478bd9Sstevel@tonic-gate * one function become required it may be worth linking the 1086*7c478bd9Sstevel@tonic-gate * entire lib. 1087*7c478bd9Sstevel@tonic-gate * 1088*7c478bd9Sstevel@tonic-gate * INPUTS: Nothing 1089*7c478bd9Sstevel@tonic-gate * 1090*7c478bd9Sstevel@tonic-gate * OUTPUTS: TRUE = Run in N2L mode 1091*7c478bd9Sstevel@tonic-gate * FALSE = Run in traditional mode. 1092*7c478bd9Sstevel@tonic-gate */ 1093*7c478bd9Sstevel@tonic-gate bool_t 1094*7c478bd9Sstevel@tonic-gate is_yptol_mode() 1095*7c478bd9Sstevel@tonic-gate { 1096*7c478bd9Sstevel@tonic-gate struct stat filestat; 1097*7c478bd9Sstevel@tonic-gate 1098*7c478bd9Sstevel@tonic-gate if (stat(NTOL_MAP_FILE, &filestat) != -1) 1099*7c478bd9Sstevel@tonic-gate return (TRUE); 1100*7c478bd9Sstevel@tonic-gate 1101*7c478bd9Sstevel@tonic-gate return (FALSE); 1102*7c478bd9Sstevel@tonic-gate } 1103