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 #ident "%Z%%M% %I% %E% SMI" 23*7c478bd9Sstevel@tonic-gate 24*7c478bd9Sstevel@tonic-gate /* 25*7c478bd9Sstevel@tonic-gate * on - user interface program for remote execution service 26*7c478bd9Sstevel@tonic-gate * 27*7c478bd9Sstevel@tonic-gate * Copyright (c) 1985 Sun Microsystems, Inc. 28*7c478bd9Sstevel@tonic-gate */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #define BSD_COMP 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate #include <ctype.h> 33*7c478bd9Sstevel@tonic-gate #include <errno.h> 34*7c478bd9Sstevel@tonic-gate #include <netdb.h> 35*7c478bd9Sstevel@tonic-gate #include <signal.h> 36*7c478bd9Sstevel@tonic-gate #include <stdio.h> 37*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 38*7c478bd9Sstevel@tonic-gate #include <string.h> 39*7c478bd9Sstevel@tonic-gate #include <unistd.h> 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate #include <netinet/in.h> 42*7c478bd9Sstevel@tonic-gate #include <rpc/rpc.h> 43*7c478bd9Sstevel@tonic-gate #include <rpc/clnt_soc.h> 44*7c478bd9Sstevel@tonic-gate #include <rpc/key_prot.h> 45*7c478bd9Sstevel@tonic-gate #include <sys/fcntl.h> 46*7c478bd9Sstevel@tonic-gate #include <sys/ioctl.h> 47*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 48*7c478bd9Sstevel@tonic-gate #include <sys/socket.h> 49*7c478bd9Sstevel@tonic-gate #include <sys/sockio.h> 50*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 51*7c478bd9Sstevel@tonic-gate #include <sys/time.h> 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate #include <sys/ttold.h> 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate #include "rex.h" 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate #include <stropts.h> 60*7c478bd9Sstevel@tonic-gate #include <sys/stream.h> 61*7c478bd9Sstevel@tonic-gate #include <sys/ttcompat.h> 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate #define bcmp(b1, b2, len) memcmp(b1, b2, len) 65*7c478bd9Sstevel@tonic-gate #define bzero(b, len) memset(b, '\0', len) 66*7c478bd9Sstevel@tonic-gate #define bcopy(b1, b2, len) memcpy(b2, b1, len) 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate #define CommandName "on" /* given as argv[0] */ 69*7c478bd9Sstevel@tonic-gate #define AltCommandName "dbon" 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate extern int errno; 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate /* 74*7c478bd9Sstevel@tonic-gate * Note - the following must be long enough for at least two portmap 75*7c478bd9Sstevel@tonic-gate * timeouts on the other side. 76*7c478bd9Sstevel@tonic-gate */ 77*7c478bd9Sstevel@tonic-gate struct timeval LongTimeout = { 123, 0 }; 78*7c478bd9Sstevel@tonic-gate struct timeval testtimeout = { 5, 0 }; 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate int Debug = 0; /* print extra debugging information */ 81*7c478bd9Sstevel@tonic-gate int Only2 = 0; /* stdout and stderr are the same */ 82*7c478bd9Sstevel@tonic-gate int Interactive = 0; /* use a pty on server */ 83*7c478bd9Sstevel@tonic-gate int NoInput = 0; /* don't read standard input */ 84*7c478bd9Sstevel@tonic-gate int child = 0; /* pid of the executed process */ 85*7c478bd9Sstevel@tonic-gate int ChildDied = 0; /* true when above is valid */ 86*7c478bd9Sstevel@tonic-gate int HasHelper = 0; /* must kill helpers (interactive mode) */ 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate int InOut; /* socket for stdin/stdout */ 89*7c478bd9Sstevel@tonic-gate int Err; /* socket for stderr */ 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate struct sgttyb OldFlags; /* saved tty flags */ 92*7c478bd9Sstevel@tonic-gate struct sgttyb NewFlags; /* for stop/continue job control */ 93*7c478bd9Sstevel@tonic-gate CLIENT *Client; /* RPC client handle */ 94*7c478bd9Sstevel@tonic-gate struct rex_ttysize WindowSize; /* saved window size */ 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate static int Argc; 97*7c478bd9Sstevel@tonic-gate static char **Argv; /* saved argument vector (for ps) */ 98*7c478bd9Sstevel@tonic-gate static char *LastArgv; /* saved end-of-argument vector */ 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate void usage(void); 101*7c478bd9Sstevel@tonic-gate void Die(int stat); 102*7c478bd9Sstevel@tonic-gate void doaccept(int *fdp); 103*7c478bd9Sstevel@tonic-gate u_short makeport(int *fdp); 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate /* 107*7c478bd9Sstevel@tonic-gate * window change handler - propagate to remote server 108*7c478bd9Sstevel@tonic-gate */ 109*7c478bd9Sstevel@tonic-gate void 110*7c478bd9Sstevel@tonic-gate sigwinch(int junk) 111*7c478bd9Sstevel@tonic-gate { 112*7c478bd9Sstevel@tonic-gate struct winsize newsize; /* the modern way to get row and col */ 113*7c478bd9Sstevel@tonic-gate struct rex_ttysize size; /* the old way no body */ 114*7c478bd9Sstevel@tonic-gate /* bothered to change */ 115*7c478bd9Sstevel@tonic-gate enum clnt_stat clstat; 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate ioctl(0, TIOCGWINSZ, &newsize); 118*7c478bd9Sstevel@tonic-gate 119*7c478bd9Sstevel@tonic-gate /* 120*7c478bd9Sstevel@tonic-gate * compensate for the struct change 121*7c478bd9Sstevel@tonic-gate */ 122*7c478bd9Sstevel@tonic-gate size.ts_lines = (int)newsize.ws_row; /* typecast important! */ 123*7c478bd9Sstevel@tonic-gate size.ts_cols = (int)newsize.ws_col; 124*7c478bd9Sstevel@tonic-gate 125*7c478bd9Sstevel@tonic-gate if (bcmp(&size, &WindowSize, sizeof (size)) == 0) 126*7c478bd9Sstevel@tonic-gate return; 127*7c478bd9Sstevel@tonic-gate 128*7c478bd9Sstevel@tonic-gate WindowSize = size; 129*7c478bd9Sstevel@tonic-gate if (clstat = clnt_call(Client, REXPROC_WINCH, 130*7c478bd9Sstevel@tonic-gate xdr_rex_ttysize, (caddr_t)&size, xdr_void, 131*7c478bd9Sstevel@tonic-gate NULL, LongTimeout)) { 132*7c478bd9Sstevel@tonic-gate fprintf(stderr, "on (size): "); 133*7c478bd9Sstevel@tonic-gate clnt_perrno(clstat); 134*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\r\n"); 135*7c478bd9Sstevel@tonic-gate } 136*7c478bd9Sstevel@tonic-gate } 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate /* 139*7c478bd9Sstevel@tonic-gate * signal handler - propagate to remote server 140*7c478bd9Sstevel@tonic-gate */ 141*7c478bd9Sstevel@tonic-gate void 142*7c478bd9Sstevel@tonic-gate sendsig(int sig) 143*7c478bd9Sstevel@tonic-gate { 144*7c478bd9Sstevel@tonic-gate enum clnt_stat clstat; 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate if (clstat = clnt_call(Client, REXPROC_SIGNAL, 147*7c478bd9Sstevel@tonic-gate xdr_int, (caddr_t) &sig, xdr_void, 148*7c478bd9Sstevel@tonic-gate NULL, LongTimeout)) { 149*7c478bd9Sstevel@tonic-gate fprintf(stderr, "on (signal): "); 150*7c478bd9Sstevel@tonic-gate clnt_perrno(clstat); 151*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\r\n"); 152*7c478bd9Sstevel@tonic-gate } 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate void 157*7c478bd9Sstevel@tonic-gate cont(int junk) 158*7c478bd9Sstevel@tonic-gate { 159*7c478bd9Sstevel@tonic-gate /* 160*7c478bd9Sstevel@tonic-gate * Put tty modes back the way they were and tell the rexd server 161*7c478bd9Sstevel@tonic-gate * to send the command a SIGCONT signal. 162*7c478bd9Sstevel@tonic-gate */ 163*7c478bd9Sstevel@tonic-gate if (Interactive) { 164*7c478bd9Sstevel@tonic-gate ioctl(0, TIOCSETN, &NewFlags); 165*7c478bd9Sstevel@tonic-gate (void) send(InOut, "", 1, MSG_OOB); 166*7c478bd9Sstevel@tonic-gate } 167*7c478bd9Sstevel@tonic-gate } 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate /* 170*7c478bd9Sstevel@tonic-gate * oob -- called when the command invoked by the rexd server is stopped 171*7c478bd9Sstevel@tonic-gate * with a SIGTSTP or SIGSTOP signal. 172*7c478bd9Sstevel@tonic-gate */ 173*7c478bd9Sstevel@tonic-gate void 174*7c478bd9Sstevel@tonic-gate oob(int junk) 175*7c478bd9Sstevel@tonic-gate { 176*7c478bd9Sstevel@tonic-gate int atmark; 177*7c478bd9Sstevel@tonic-gate char waste[BUFSIZ], mark; 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate for (;;) { 180*7c478bd9Sstevel@tonic-gate if (ioctl(InOut, SIOCATMARK, &atmark) < 0) { 181*7c478bd9Sstevel@tonic-gate perror("ioctl"); 182*7c478bd9Sstevel@tonic-gate break; 183*7c478bd9Sstevel@tonic-gate } 184*7c478bd9Sstevel@tonic-gate if (atmark) 185*7c478bd9Sstevel@tonic-gate break; 186*7c478bd9Sstevel@tonic-gate (void) read(InOut, waste, sizeof (waste)); 187*7c478bd9Sstevel@tonic-gate } 188*7c478bd9Sstevel@tonic-gate (void) recv(InOut, &mark, 1, MSG_OOB); 189*7c478bd9Sstevel@tonic-gate /* 190*7c478bd9Sstevel@tonic-gate * Reset tty modes to something sane and stop myself 191*7c478bd9Sstevel@tonic-gate */ 192*7c478bd9Sstevel@tonic-gate if (Interactive) { 193*7c478bd9Sstevel@tonic-gate ioctl(0, TIOCSETN, &OldFlags); 194*7c478bd9Sstevel@tonic-gate printf("\r\n"); 195*7c478bd9Sstevel@tonic-gate } 196*7c478bd9Sstevel@tonic-gate kill(getpid(), SIGSTOP); 197*7c478bd9Sstevel@tonic-gate } 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate void 202*7c478bd9Sstevel@tonic-gate main(int argc, char **argv) 203*7c478bd9Sstevel@tonic-gate { 204*7c478bd9Sstevel@tonic-gate struct winsize newsize; /* the modern way to get row and col */ 205*7c478bd9Sstevel@tonic-gate char *rhost, **cmdp; 206*7c478bd9Sstevel@tonic-gate char curdir[MAXPATHLEN]; 207*7c478bd9Sstevel@tonic-gate char wdhost[MAXHOSTNAMELEN]; 208*7c478bd9Sstevel@tonic-gate char fsname[MAXPATHLEN]; 209*7c478bd9Sstevel@tonic-gate char dirwithin[MAXPATHLEN]; 210*7c478bd9Sstevel@tonic-gate struct rex_start rst; 211*7c478bd9Sstevel@tonic-gate struct rex_result result; 212*7c478bd9Sstevel@tonic-gate extern char **environ; 213*7c478bd9Sstevel@tonic-gate enum clnt_stat clstat; 214*7c478bd9Sstevel@tonic-gate struct hostent *hp; 215*7c478bd9Sstevel@tonic-gate struct sockaddr_in server_addr; 216*7c478bd9Sstevel@tonic-gate int sock = RPC_ANYSOCK; 217*7c478bd9Sstevel@tonic-gate fd_set selmask, zmask, remmask; 218*7c478bd9Sstevel@tonic-gate int nfds, cc; 219*7c478bd9Sstevel@tonic-gate char *chi, *cho; 220*7c478bd9Sstevel@tonic-gate int trying_authdes; 221*7c478bd9Sstevel@tonic-gate char netname[MAXNETNAMELEN+1]; 222*7c478bd9Sstevel@tonic-gate char hostname[MAXHOSTNAMELEN+1]; 223*7c478bd9Sstevel@tonic-gate char publickey[HEXKEYBYTES+1]; 224*7c478bd9Sstevel@tonic-gate int i; 225*7c478bd9Sstevel@tonic-gate char *domain; 226*7c478bd9Sstevel@tonic-gate static char buf[4096]; 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate /* 229*7c478bd9Sstevel@tonic-gate * we check the invoked command name to see if it should 230*7c478bd9Sstevel@tonic-gate * really be a host name. 231*7c478bd9Sstevel@tonic-gate */ 232*7c478bd9Sstevel@tonic-gate if ((rhost = strrchr(argv[0], '/')) == NULL) { 233*7c478bd9Sstevel@tonic-gate rhost = argv[0]; 234*7c478bd9Sstevel@tonic-gate } else { 235*7c478bd9Sstevel@tonic-gate rhost++; 236*7c478bd9Sstevel@tonic-gate } 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate /* 239*7c478bd9Sstevel@tonic-gate * argv start and extent for setproctitle() 240*7c478bd9Sstevel@tonic-gate */ 241*7c478bd9Sstevel@tonic-gate Argc = argc; 242*7c478bd9Sstevel@tonic-gate Argv = argv; 243*7c478bd9Sstevel@tonic-gate if (argc > 0) 244*7c478bd9Sstevel@tonic-gate LastArgv = argv[argc-1] + strlen(argv[argc-1]); 245*7c478bd9Sstevel@tonic-gate else 246*7c478bd9Sstevel@tonic-gate LastArgv = NULL; 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate while (argc > 1 && argv[1][0] == '-') { 249*7c478bd9Sstevel@tonic-gate switch (argv[1][1]) { 250*7c478bd9Sstevel@tonic-gate case 'd': Debug = 1; 251*7c478bd9Sstevel@tonic-gate break; 252*7c478bd9Sstevel@tonic-gate case 'i': Interactive = 1; 253*7c478bd9Sstevel@tonic-gate break; 254*7c478bd9Sstevel@tonic-gate case 'n': NoInput = 1; 255*7c478bd9Sstevel@tonic-gate break; 256*7c478bd9Sstevel@tonic-gate default: 257*7c478bd9Sstevel@tonic-gate printf("Unknown option %s\n", argv[1]); 258*7c478bd9Sstevel@tonic-gate } 259*7c478bd9Sstevel@tonic-gate argv++; 260*7c478bd9Sstevel@tonic-gate argc--; 261*7c478bd9Sstevel@tonic-gate } 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate if (strcmp(rhost, CommandName) && strcmp(rhost, AltCommandName)) { 264*7c478bd9Sstevel@tonic-gate cmdp = &argv[1]; 265*7c478bd9Sstevel@tonic-gate Interactive = 1; 266*7c478bd9Sstevel@tonic-gate } else { 267*7c478bd9Sstevel@tonic-gate if (argc < 2) 268*7c478bd9Sstevel@tonic-gate usage(); 269*7c478bd9Sstevel@tonic-gate rhost = argv[1]; 270*7c478bd9Sstevel@tonic-gate cmdp = &argv[2]; 271*7c478bd9Sstevel@tonic-gate } 272*7c478bd9Sstevel@tonic-gate 273*7c478bd9Sstevel@tonic-gate /* 274*7c478bd9Sstevel@tonic-gate * Can only have one of these 275*7c478bd9Sstevel@tonic-gate */ 276*7c478bd9Sstevel@tonic-gate if (Interactive && NoInput) 277*7c478bd9Sstevel@tonic-gate usage(); 278*7c478bd9Sstevel@tonic-gate 279*7c478bd9Sstevel@tonic-gate if ((hp = gethostbyname(rhost)) == NULL) { 280*7c478bd9Sstevel@tonic-gate fprintf(stderr, "on: unknown host %s\n", rhost); 281*7c478bd9Sstevel@tonic-gate exit(1); 282*7c478bd9Sstevel@tonic-gate } 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr, hp->h_length); 285*7c478bd9Sstevel@tonic-gate server_addr.sin_family = AF_INET; 286*7c478bd9Sstevel@tonic-gate server_addr.sin_port = 0; /* use pmapper */ 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate if (Debug) 289*7c478bd9Sstevel@tonic-gate printf("Got the host named %s (%s)\n", 290*7c478bd9Sstevel@tonic-gate rhost, inet_ntoa(server_addr.sin_addr)); 291*7c478bd9Sstevel@tonic-gate trying_authdes = 1; 292*7c478bd9Sstevel@tonic-gate 293*7c478bd9Sstevel@tonic-gate try_auth_unix: 294*7c478bd9Sstevel@tonic-gate sock = RPC_ANYSOCK; 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate if (Debug) 297*7c478bd9Sstevel@tonic-gate printf("clnt_create: Server_Addr %u Prog %d Vers %d Sock %d\n", 298*7c478bd9Sstevel@tonic-gate &server_addr, REXPROG, REXVERS, sock); 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate if ((Client = clnttcp_create(&server_addr, REXPROG, REXVERS, &sock, 301*7c478bd9Sstevel@tonic-gate 0, 0)) == NULL) { 302*7c478bd9Sstevel@tonic-gate fprintf(stderr, "on: cannot connect to server on %s\n", 303*7c478bd9Sstevel@tonic-gate rhost); 304*7c478bd9Sstevel@tonic-gate clnt_pcreateerror("on:"); 305*7c478bd9Sstevel@tonic-gate exit(1); 306*7c478bd9Sstevel@tonic-gate } 307*7c478bd9Sstevel@tonic-gate 308*7c478bd9Sstevel@tonic-gate if (Debug) 309*7c478bd9Sstevel@tonic-gate printf("TCP RPC connection created\n"); 310*7c478bd9Sstevel@tonic-gate 311*7c478bd9Sstevel@tonic-gate if (trying_authdes) { 312*7c478bd9Sstevel@tonic-gate yp_get_default_domain(&domain); 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate cho = hostname; 315*7c478bd9Sstevel@tonic-gate *cho = 0; 316*7c478bd9Sstevel@tonic-gate chi = hp->h_name; 317*7c478bd9Sstevel@tonic-gate 318*7c478bd9Sstevel@tonic-gate for (i = 0; (*chi && (i < MAXHOSTNAMELEN)); i++) 319*7c478bd9Sstevel@tonic-gate { 320*7c478bd9Sstevel@tonic-gate if (isupper(*chi)) 321*7c478bd9Sstevel@tonic-gate *cho = tolower(*chi); 322*7c478bd9Sstevel@tonic-gate else 323*7c478bd9Sstevel@tonic-gate *cho = *chi; 324*7c478bd9Sstevel@tonic-gate cho++; 325*7c478bd9Sstevel@tonic-gate chi++; 326*7c478bd9Sstevel@tonic-gate } 327*7c478bd9Sstevel@tonic-gate *cho = 0; 328*7c478bd9Sstevel@tonic-gate 329*7c478bd9Sstevel@tonic-gate if (domain != NULL) { 330*7c478bd9Sstevel@tonic-gate if (host2netname(netname, hostname, domain) == 0) { 331*7c478bd9Sstevel@tonic-gate trying_authdes = 0; 332*7c478bd9Sstevel@tonic-gate if (Debug) 333*7c478bd9Sstevel@tonic-gate printf("host2netname failed %s\n", 334*7c478bd9Sstevel@tonic-gate hp->h_name); 335*7c478bd9Sstevel@tonic-gate } 336*7c478bd9Sstevel@tonic-gate /* #ifdef NOWAY */ 337*7c478bd9Sstevel@tonic-gate else { 338*7c478bd9Sstevel@tonic-gate 339*7c478bd9Sstevel@tonic-gate if (getpublickey(netname, publickey) == 0) { 340*7c478bd9Sstevel@tonic-gate trying_authdes = 0; 341*7c478bd9Sstevel@tonic-gate cho = strchr(hostname, '.'); 342*7c478bd9Sstevel@tonic-gate 343*7c478bd9Sstevel@tonic-gate if (cho) { 344*7c478bd9Sstevel@tonic-gate *cho = 0; 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate if (!host2netname(netname, 347*7c478bd9Sstevel@tonic-gate hostname, 348*7c478bd9Sstevel@tonic-gate domain)) { 349*7c478bd9Sstevel@tonic-gate if (Debug) 350*7c478bd9Sstevel@tonic-gate printf("host2netname failed %s\n", hp->h_name); 351*7c478bd9Sstevel@tonic-gate } else { 352*7c478bd9Sstevel@tonic-gate if (getpublickey( 353*7c478bd9Sstevel@tonic-gate netname, 354*7c478bd9Sstevel@tonic-gate publickey) != 0) 355*7c478bd9Sstevel@tonic-gate trying_authdes = 1; 356*7c478bd9Sstevel@tonic-gate } 357*7c478bd9Sstevel@tonic-gate } 358*7c478bd9Sstevel@tonic-gate } 359*7c478bd9Sstevel@tonic-gate } 360*7c478bd9Sstevel@tonic-gate } else { 361*7c478bd9Sstevel@tonic-gate trying_authdes = 0; 362*7c478bd9Sstevel@tonic-gate if (Debug) 363*7c478bd9Sstevel@tonic-gate printf("yp_get_default_domain failed \n"); 364*7c478bd9Sstevel@tonic-gate } 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate if (trying_authdes) { 368*7c478bd9Sstevel@tonic-gate Client->cl_auth = (AUTH *)authdes_create(netname, 60*60, 369*7c478bd9Sstevel@tonic-gate &server_addr, NULL); 370*7c478bd9Sstevel@tonic-gate 371*7c478bd9Sstevel@tonic-gate if (Client->cl_auth == NULL) { 372*7c478bd9Sstevel@tonic-gate 373*7c478bd9Sstevel@tonic-gate if (Debug) 374*7c478bd9Sstevel@tonic-gate printf("authdes_create failed %s\n", netname); 375*7c478bd9Sstevel@tonic-gate trying_authdes = 0; 376*7c478bd9Sstevel@tonic-gate } 377*7c478bd9Sstevel@tonic-gate } 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gate 380*7c478bd9Sstevel@tonic-gate if (trying_authdes == 0) 381*7c478bd9Sstevel@tonic-gate if ((Client->cl_auth = authsys_create_default()) == NULL) { 382*7c478bd9Sstevel@tonic-gate clnt_destroy(Client); 383*7c478bd9Sstevel@tonic-gate fprintf(stderr,"on: can't create authunix structure.\n"); 384*7c478bd9Sstevel@tonic-gate exit(1); 385*7c478bd9Sstevel@tonic-gate } 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate 388*7c478bd9Sstevel@tonic-gate /* 389*7c478bd9Sstevel@tonic-gate * Now that we have created the TCP connection, we do some 390*7c478bd9Sstevel@tonic-gate * work while the server daemon is being swapped in. 391*7c478bd9Sstevel@tonic-gate */ 392*7c478bd9Sstevel@tonic-gate if (getcwd(curdir, MAXPATHLEN) == (char *)NULL) { 393*7c478bd9Sstevel@tonic-gate fprintf(stderr, "on: can't find . (%s)\n", curdir); 394*7c478bd9Sstevel@tonic-gate exit(1); 395*7c478bd9Sstevel@tonic-gate } 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate if (findmount(curdir, wdhost, fsname, dirwithin) == 0) { 398*7c478bd9Sstevel@tonic-gate 399*7c478bd9Sstevel@tonic-gate if (Debug) { 400*7c478bd9Sstevel@tonic-gate fprintf(stderr, 401*7c478bd9Sstevel@tonic-gate "findmount failed: curdir %s\twdhost %s\t", 402*7c478bd9Sstevel@tonic-gate curdir, wdhost); 403*7c478bd9Sstevel@tonic-gate fprintf(stderr, "fsname %s\tdirwithin %s\n", 404*7c478bd9Sstevel@tonic-gate fsname, dirwithin); 405*7c478bd9Sstevel@tonic-gate } 406*7c478bd9Sstevel@tonic-gate 407*7c478bd9Sstevel@tonic-gate fprintf(stderr, "on: can't locate mount point for %s (%s)\n", 408*7c478bd9Sstevel@tonic-gate curdir, dirwithin); 409*7c478bd9Sstevel@tonic-gate exit(1); 410*7c478bd9Sstevel@tonic-gate } 411*7c478bd9Sstevel@tonic-gate 412*7c478bd9Sstevel@tonic-gate if (Debug) { 413*7c478bd9Sstevel@tonic-gate printf("findmount suceeds: cwd= %s, wd host %s, fs %s,", 414*7c478bd9Sstevel@tonic-gate curdir, wdhost, fsname); 415*7c478bd9Sstevel@tonic-gate printf("dir within %s\n", dirwithin); 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate Only2 = samefd(1, 2); 419*7c478bd9Sstevel@tonic-gate 420*7c478bd9Sstevel@tonic-gate rst.rst_cmd = (void *)(cmdp); 421*7c478bd9Sstevel@tonic-gate rst.rst_host = (void *)wdhost; 422*7c478bd9Sstevel@tonic-gate rst.rst_fsname = (void *)fsname; 423*7c478bd9Sstevel@tonic-gate rst.rst_dirwithin = (void *)dirwithin; 424*7c478bd9Sstevel@tonic-gate rst.rst_env = (void *)environ; 425*7c478bd9Sstevel@tonic-gate rst.rst_port0 = makeport(&InOut); 426*7c478bd9Sstevel@tonic-gate rst.rst_port1 = rst.rst_port0; /* same port for stdin */ 427*7c478bd9Sstevel@tonic-gate rst.rst_flags = 0; 428*7c478bd9Sstevel@tonic-gate 429*7c478bd9Sstevel@tonic-gate if (Debug) 430*7c478bd9Sstevel@tonic-gate printf("before Interactive flags\n"); 431*7c478bd9Sstevel@tonic-gate 432*7c478bd9Sstevel@tonic-gate if (Interactive) { 433*7c478bd9Sstevel@tonic-gate rst.rst_flags |= REX_INTERACTIVE; 434*7c478bd9Sstevel@tonic-gate ioctl(0, TIOCGETP, &OldFlags); 435*7c478bd9Sstevel@tonic-gate NewFlags = OldFlags; 436*7c478bd9Sstevel@tonic-gate NewFlags.sg_flags |= (u_int)RAW; 437*7c478bd9Sstevel@tonic-gate NewFlags.sg_flags &= (u_int)~ECHO; 438*7c478bd9Sstevel@tonic-gate ioctl(0, TIOCSETN, &NewFlags); 439*7c478bd9Sstevel@tonic-gate } 440*7c478bd9Sstevel@tonic-gate 441*7c478bd9Sstevel@tonic-gate if (Only2) { 442*7c478bd9Sstevel@tonic-gate rst.rst_port2 = rst.rst_port1; 443*7c478bd9Sstevel@tonic-gate } else { 444*7c478bd9Sstevel@tonic-gate rst.rst_port2 = makeport(&Err); 445*7c478bd9Sstevel@tonic-gate } 446*7c478bd9Sstevel@tonic-gate 447*7c478bd9Sstevel@tonic-gate if (Debug) 448*7c478bd9Sstevel@tonic-gate printf("before client call REXPROC_START\n"); 449*7c478bd9Sstevel@tonic-gate 450*7c478bd9Sstevel@tonic-gate (void) memset(&result, '\0', sizeof(result)); 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate if (clstat = clnt_call(Client, REXPROC_START, 453*7c478bd9Sstevel@tonic-gate xdr_rex_start, (caddr_t)&rst, 454*7c478bd9Sstevel@tonic-gate xdr_rex_result, (caddr_t)&result, LongTimeout)) { 455*7c478bd9Sstevel@tonic-gate 456*7c478bd9Sstevel@tonic-gate if (Debug) 457*7c478bd9Sstevel@tonic-gate printf("Client call failed for REXPROC_START\r\n"); 458*7c478bd9Sstevel@tonic-gate 459*7c478bd9Sstevel@tonic-gate if (trying_authdes) { 460*7c478bd9Sstevel@tonic-gate auth_destroy(Client->cl_auth); 461*7c478bd9Sstevel@tonic-gate clnt_destroy(Client); 462*7c478bd9Sstevel@tonic-gate trying_authdes = 0; 463*7c478bd9Sstevel@tonic-gate if (Interactive) 464*7c478bd9Sstevel@tonic-gate ioctl(0, TIOCSETN, &OldFlags); 465*7c478bd9Sstevel@tonic-gate goto try_auth_unix; 466*7c478bd9Sstevel@tonic-gate } else { 467*7c478bd9Sstevel@tonic-gate fprintf(stderr, "on %s: ", rhost); 468*7c478bd9Sstevel@tonic-gate clnt_perrno(clstat); 469*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\n"); 470*7c478bd9Sstevel@tonic-gate Die(1); 471*7c478bd9Sstevel@tonic-gate } 472*7c478bd9Sstevel@tonic-gate } 473*7c478bd9Sstevel@tonic-gate 474*7c478bd9Sstevel@tonic-gate if (result.rlt_stat != 0) { 475*7c478bd9Sstevel@tonic-gate fprintf(stderr, "on %s: %s\n\r", rhost, result.rlt_message); 476*7c478bd9Sstevel@tonic-gate Die(1); 477*7c478bd9Sstevel@tonic-gate } 478*7c478bd9Sstevel@tonic-gate 479*7c478bd9Sstevel@tonic-gate clnt_freeres(Client, xdr_rex_result, (caddr_t)&result); 480*7c478bd9Sstevel@tonic-gate 481*7c478bd9Sstevel@tonic-gate if (Debug) 482*7c478bd9Sstevel@tonic-gate printf("Client call suceeded for REXPROC_START\r\n"); 483*7c478bd9Sstevel@tonic-gate 484*7c478bd9Sstevel@tonic-gate if (Interactive) { 485*7c478bd9Sstevel@tonic-gate /* 486*7c478bd9Sstevel@tonic-gate * Pass the tty modes along to the server 487*7c478bd9Sstevel@tonic-gate */ 488*7c478bd9Sstevel@tonic-gate struct rex_ttymode mode; 489*7c478bd9Sstevel@tonic-gate int err; 490*7c478bd9Sstevel@tonic-gate 491*7c478bd9Sstevel@tonic-gate mode.basic.sg_ispeed = OldFlags.sg_ispeed; 492*7c478bd9Sstevel@tonic-gate mode.basic.sg_ospeed = OldFlags.sg_ospeed; 493*7c478bd9Sstevel@tonic-gate mode.basic.sg_erase = OldFlags.sg_erase; 494*7c478bd9Sstevel@tonic-gate mode.basic.sg_kill = OldFlags.sg_kill; 495*7c478bd9Sstevel@tonic-gate mode.basic.sg_flags = (short) (OldFlags.sg_flags & 0xFFFF); 496*7c478bd9Sstevel@tonic-gate err = (ioctl(0, TIOCGETC, &mode.more) < 0 || 497*7c478bd9Sstevel@tonic-gate ioctl(0, TIOCGLTC, &mode.yetmore) < 0 || 498*7c478bd9Sstevel@tonic-gate ioctl(0, TIOCLGET, &mode.andmore) < 0); 499*7c478bd9Sstevel@tonic-gate if (Debug) 500*7c478bd9Sstevel@tonic-gate printf("Before clnt_call(REXPROC_MODES) err=%d\n", err); 501*7c478bd9Sstevel@tonic-gate 502*7c478bd9Sstevel@tonic-gate if (!err && (clstat = clnt_call(Client, REXPROC_MODES, 503*7c478bd9Sstevel@tonic-gate xdr_rex_ttymode, (caddr_t)&mode, 504*7c478bd9Sstevel@tonic-gate xdr_void, NULL, LongTimeout))) { 505*7c478bd9Sstevel@tonic-gate 506*7c478bd9Sstevel@tonic-gate fprintf(stderr, "on (modes) %s: ", rhost); 507*7c478bd9Sstevel@tonic-gate clnt_perrno(clstat); 508*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\r\n"); 509*7c478bd9Sstevel@tonic-gate } 510*7c478bd9Sstevel@tonic-gate 511*7c478bd9Sstevel@tonic-gate err = ioctl(0, TIOCGWINSZ, &newsize) < 0; 512*7c478bd9Sstevel@tonic-gate /* typecast important in following lines */ 513*7c478bd9Sstevel@tonic-gate WindowSize.ts_lines = (int)newsize.ws_row; 514*7c478bd9Sstevel@tonic-gate WindowSize.ts_cols = (int)newsize.ws_col; 515*7c478bd9Sstevel@tonic-gate 516*7c478bd9Sstevel@tonic-gate if (Debug) 517*7c478bd9Sstevel@tonic-gate printf("Before client call REXPROC_WINCH\n"); 518*7c478bd9Sstevel@tonic-gate 519*7c478bd9Sstevel@tonic-gate if (!err && (clstat = clnt_call(Client, REXPROC_WINCH, 520*7c478bd9Sstevel@tonic-gate xdr_rex_ttysize, (caddr_t)&WindowSize, 521*7c478bd9Sstevel@tonic-gate xdr_void, NULL, LongTimeout))) { 522*7c478bd9Sstevel@tonic-gate 523*7c478bd9Sstevel@tonic-gate fprintf(stderr, "on (size) %s: ", rhost); 524*7c478bd9Sstevel@tonic-gate clnt_perrno(clstat); 525*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\r\n"); 526*7c478bd9Sstevel@tonic-gate } 527*7c478bd9Sstevel@tonic-gate 528*7c478bd9Sstevel@tonic-gate sigset(SIGWINCH, sigwinch); 529*7c478bd9Sstevel@tonic-gate sigset(SIGINT, sendsig); 530*7c478bd9Sstevel@tonic-gate sigset(SIGQUIT, sendsig); 531*7c478bd9Sstevel@tonic-gate sigset(SIGTERM, sendsig); 532*7c478bd9Sstevel@tonic-gate } 533*7c478bd9Sstevel@tonic-gate sigset(SIGCONT, cont); 534*7c478bd9Sstevel@tonic-gate sigset(SIGURG, oob); 535*7c478bd9Sstevel@tonic-gate doaccept(&InOut); 536*7c478bd9Sstevel@tonic-gate (void) fcntl(InOut, F_SETOWN, getpid()); 537*7c478bd9Sstevel@tonic-gate FD_ZERO(&remmask); 538*7c478bd9Sstevel@tonic-gate FD_SET(InOut, &remmask); 539*7c478bd9Sstevel@tonic-gate if (Debug) 540*7c478bd9Sstevel@tonic-gate printf("accept on stdout\r\n"); 541*7c478bd9Sstevel@tonic-gate 542*7c478bd9Sstevel@tonic-gate if (!Only2) { 543*7c478bd9Sstevel@tonic-gate 544*7c478bd9Sstevel@tonic-gate doaccept(&Err); 545*7c478bd9Sstevel@tonic-gate shutdown(Err, 1); /* 1=> further sends disallowed */ 546*7c478bd9Sstevel@tonic-gate if (Debug) 547*7c478bd9Sstevel@tonic-gate printf("accept on stderr\r\n"); 548*7c478bd9Sstevel@tonic-gate FD_SET(Err, &remmask); 549*7c478bd9Sstevel@tonic-gate } 550*7c478bd9Sstevel@tonic-gate 551*7c478bd9Sstevel@tonic-gate FD_ZERO(&zmask); 552*7c478bd9Sstevel@tonic-gate if (NoInput) { 553*7c478bd9Sstevel@tonic-gate 554*7c478bd9Sstevel@tonic-gate /* 555*7c478bd9Sstevel@tonic-gate * no input - simulate end-of-file instead 556*7c478bd9Sstevel@tonic-gate */ 557*7c478bd9Sstevel@tonic-gate shutdown(InOut, 1); /* 1=> further sends disallowed */ 558*7c478bd9Sstevel@tonic-gate } else { 559*7c478bd9Sstevel@tonic-gate /* 560*7c478bd9Sstevel@tonic-gate * set up to read standard input, send to remote 561*7c478bd9Sstevel@tonic-gate */ 562*7c478bd9Sstevel@tonic-gate FD_SET(0, &zmask); 563*7c478bd9Sstevel@tonic-gate } 564*7c478bd9Sstevel@tonic-gate 565*7c478bd9Sstevel@tonic-gate FD_ZERO(&selmask); 566*7c478bd9Sstevel@tonic-gate while (FD_ISSET(InOut, &remmask) || FD_ISSET(Err, &remmask)) { 567*7c478bd9Sstevel@tonic-gate if (FD_ISSET(InOut, &remmask)) 568*7c478bd9Sstevel@tonic-gate FD_SET(InOut, &selmask); 569*7c478bd9Sstevel@tonic-gate else 570*7c478bd9Sstevel@tonic-gate FD_CLR(InOut, &selmask); 571*7c478bd9Sstevel@tonic-gate if (FD_ISSET(Err, &remmask)) 572*7c478bd9Sstevel@tonic-gate FD_SET(Err, &selmask); 573*7c478bd9Sstevel@tonic-gate else 574*7c478bd9Sstevel@tonic-gate FD_CLR(Err, &selmask); 575*7c478bd9Sstevel@tonic-gate if (FD_ISSET(0, &zmask)) 576*7c478bd9Sstevel@tonic-gate FD_SET(0, &selmask); 577*7c478bd9Sstevel@tonic-gate else 578*7c478bd9Sstevel@tonic-gate FD_CLR(0, &selmask); 579*7c478bd9Sstevel@tonic-gate nfds = select(FD_SETSIZE, &selmask, (fd_set *) 0, (fd_set *) 0, 580*7c478bd9Sstevel@tonic-gate (struct timeval *) 0); 581*7c478bd9Sstevel@tonic-gate 582*7c478bd9Sstevel@tonic-gate 583*7c478bd9Sstevel@tonic-gate if (nfds <= 0) { 584*7c478bd9Sstevel@tonic-gate if (errno == EINTR) continue; 585*7c478bd9Sstevel@tonic-gate perror("on: select"); 586*7c478bd9Sstevel@tonic-gate Die(1); 587*7c478bd9Sstevel@tonic-gate } 588*7c478bd9Sstevel@tonic-gate if (FD_ISSET(InOut, &selmask)) { 589*7c478bd9Sstevel@tonic-gate 590*7c478bd9Sstevel@tonic-gate cc = read(InOut, buf, sizeof buf); 591*7c478bd9Sstevel@tonic-gate if (cc > 0) 592*7c478bd9Sstevel@tonic-gate write(1, buf, cc); 593*7c478bd9Sstevel@tonic-gate else 594*7c478bd9Sstevel@tonic-gate FD_CLR(InOut, &remmask); 595*7c478bd9Sstevel@tonic-gate } 596*7c478bd9Sstevel@tonic-gate 597*7c478bd9Sstevel@tonic-gate if (!Only2 && FD_ISSET(Err, &selmask)) { 598*7c478bd9Sstevel@tonic-gate 599*7c478bd9Sstevel@tonic-gate cc = read(Err, buf, sizeof buf); 600*7c478bd9Sstevel@tonic-gate if (cc > 0) 601*7c478bd9Sstevel@tonic-gate write(2, buf, cc); 602*7c478bd9Sstevel@tonic-gate else 603*7c478bd9Sstevel@tonic-gate FD_CLR(Err, &remmask); 604*7c478bd9Sstevel@tonic-gate } 605*7c478bd9Sstevel@tonic-gate 606*7c478bd9Sstevel@tonic-gate if (!NoInput && FD_ISSET(0, &selmask)) { 607*7c478bd9Sstevel@tonic-gate 608*7c478bd9Sstevel@tonic-gate cc = read(0, buf, sizeof buf); 609*7c478bd9Sstevel@tonic-gate if (cc > 0) 610*7c478bd9Sstevel@tonic-gate write(InOut, buf, cc); 611*7c478bd9Sstevel@tonic-gate else { 612*7c478bd9Sstevel@tonic-gate /* 613*7c478bd9Sstevel@tonic-gate * End of standard input - shutdown outgoing 614*7c478bd9Sstevel@tonic-gate * direction of the TCP connection. 615*7c478bd9Sstevel@tonic-gate */ 616*7c478bd9Sstevel@tonic-gate if (Debug) 617*7c478bd9Sstevel@tonic-gate printf("Got EOF - shutting down connection\n"); 618*7c478bd9Sstevel@tonic-gate FD_CLR(0, &zmask); 619*7c478bd9Sstevel@tonic-gate shutdown(InOut, 1); /* further sends disallowed */ 620*7c478bd9Sstevel@tonic-gate } 621*7c478bd9Sstevel@tonic-gate } 622*7c478bd9Sstevel@tonic-gate } 623*7c478bd9Sstevel@tonic-gate 624*7c478bd9Sstevel@tonic-gate close(InOut); 625*7c478bd9Sstevel@tonic-gate if (!Only2) 626*7c478bd9Sstevel@tonic-gate close(Err); 627*7c478bd9Sstevel@tonic-gate 628*7c478bd9Sstevel@tonic-gate (void) memset(&result, '\0', sizeof(result)); 629*7c478bd9Sstevel@tonic-gate 630*7c478bd9Sstevel@tonic-gate if (clstat = clnt_call(Client, REXPROC_WAIT, 631*7c478bd9Sstevel@tonic-gate xdr_void, 0, xdr_rex_result, (caddr_t)&result, 632*7c478bd9Sstevel@tonic-gate LongTimeout)) { 633*7c478bd9Sstevel@tonic-gate 634*7c478bd9Sstevel@tonic-gate fprintf(stderr, "on: "); 635*7c478bd9Sstevel@tonic-gate clnt_perrno(clstat); 636*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\r\n"); 637*7c478bd9Sstevel@tonic-gate Die(1); 638*7c478bd9Sstevel@tonic-gate } 639*7c478bd9Sstevel@tonic-gate Die(result.rlt_stat); 640*7c478bd9Sstevel@tonic-gate } 641*7c478bd9Sstevel@tonic-gate 642*7c478bd9Sstevel@tonic-gate /* 643*7c478bd9Sstevel@tonic-gate * like exit, but resets the terminal state first 644*7c478bd9Sstevel@tonic-gate */ 645*7c478bd9Sstevel@tonic-gate void 646*7c478bd9Sstevel@tonic-gate Die(int stat) 647*7c478bd9Sstevel@tonic-gate 648*7c478bd9Sstevel@tonic-gate { 649*7c478bd9Sstevel@tonic-gate if (Interactive) { 650*7c478bd9Sstevel@tonic-gate ioctl(0, TIOCSETN, &OldFlags); 651*7c478bd9Sstevel@tonic-gate printf("\r\n"); 652*7c478bd9Sstevel@tonic-gate } 653*7c478bd9Sstevel@tonic-gate exit(stat); 654*7c478bd9Sstevel@tonic-gate } 655*7c478bd9Sstevel@tonic-gate 656*7c478bd9Sstevel@tonic-gate 657*7c478bd9Sstevel@tonic-gate void 658*7c478bd9Sstevel@tonic-gate remstop() 659*7c478bd9Sstevel@tonic-gate 660*7c478bd9Sstevel@tonic-gate { 661*7c478bd9Sstevel@tonic-gate Die(23); 662*7c478bd9Sstevel@tonic-gate } 663*7c478bd9Sstevel@tonic-gate 664*7c478bd9Sstevel@tonic-gate /* 665*7c478bd9Sstevel@tonic-gate * returns true if we can safely say that the two file descriptors 666*7c478bd9Sstevel@tonic-gate * are the "same" (both are same file). 667*7c478bd9Sstevel@tonic-gate */ 668*7c478bd9Sstevel@tonic-gate int 669*7c478bd9Sstevel@tonic-gate samefd(a, b) 670*7c478bd9Sstevel@tonic-gate { 671*7c478bd9Sstevel@tonic-gate struct stat astat, bstat; 672*7c478bd9Sstevel@tonic-gate 673*7c478bd9Sstevel@tonic-gate if (fstat(a, &astat) || fstat(b, &bstat)) 674*7c478bd9Sstevel@tonic-gate return (0); 675*7c478bd9Sstevel@tonic-gate if (astat.st_ino == 0 || bstat.st_ino == 0) 676*7c478bd9Sstevel@tonic-gate return (0); 677*7c478bd9Sstevel@tonic-gate return (!bcmp(&astat, &bstat, sizeof (astat))); 678*7c478bd9Sstevel@tonic-gate } 679*7c478bd9Sstevel@tonic-gate 680*7c478bd9Sstevel@tonic-gate 681*7c478bd9Sstevel@tonic-gate /* 682*7c478bd9Sstevel@tonic-gate * accept the incoming connection on the given 683*7c478bd9Sstevel@tonic-gate * file descriptor, and return the new file descritpor 684*7c478bd9Sstevel@tonic-gate */ 685*7c478bd9Sstevel@tonic-gate void 686*7c478bd9Sstevel@tonic-gate doaccept(fdp) 687*7c478bd9Sstevel@tonic-gate int *fdp; 688*7c478bd9Sstevel@tonic-gate { 689*7c478bd9Sstevel@tonic-gate int fd; 690*7c478bd9Sstevel@tonic-gate 691*7c478bd9Sstevel@tonic-gate fd = accept(*fdp, 0, 0); 692*7c478bd9Sstevel@tonic-gate 693*7c478bd9Sstevel@tonic-gate if (fd < 0) { 694*7c478bd9Sstevel@tonic-gate perror("accept"); 695*7c478bd9Sstevel@tonic-gate remstop(); 696*7c478bd9Sstevel@tonic-gate } 697*7c478bd9Sstevel@tonic-gate close(*fdp); 698*7c478bd9Sstevel@tonic-gate *fdp = fd; 699*7c478bd9Sstevel@tonic-gate } 700*7c478bd9Sstevel@tonic-gate 701*7c478bd9Sstevel@tonic-gate /* 702*7c478bd9Sstevel@tonic-gate * create a socket, and return its the port number. 703*7c478bd9Sstevel@tonic-gate */ 704*7c478bd9Sstevel@tonic-gate u_short 705*7c478bd9Sstevel@tonic-gate makeport(fdp) 706*7c478bd9Sstevel@tonic-gate int *fdp; 707*7c478bd9Sstevel@tonic-gate { 708*7c478bd9Sstevel@tonic-gate struct sockaddr_in sin; 709*7c478bd9Sstevel@tonic-gate socklen_t len = (socklen_t)sizeof (sin); 710*7c478bd9Sstevel@tonic-gate int fd; 711*7c478bd9Sstevel@tonic-gate 712*7c478bd9Sstevel@tonic-gate fd = socket(AF_INET, SOCK_STREAM, 0); 713*7c478bd9Sstevel@tonic-gate 714*7c478bd9Sstevel@tonic-gate if (fd < 0) { 715*7c478bd9Sstevel@tonic-gate perror("socket"); 716*7c478bd9Sstevel@tonic-gate exit(1); 717*7c478bd9Sstevel@tonic-gate } 718*7c478bd9Sstevel@tonic-gate 719*7c478bd9Sstevel@tonic-gate bzero((char *)&sin, sizeof (sin)); 720*7c478bd9Sstevel@tonic-gate sin.sin_family = AF_INET; 721*7c478bd9Sstevel@tonic-gate bind(fd, (struct sockaddr *)&sin, sizeof (sin)); 722*7c478bd9Sstevel@tonic-gate getsockname(fd, (struct sockaddr *)&sin, &len); 723*7c478bd9Sstevel@tonic-gate listen(fd, 1); 724*7c478bd9Sstevel@tonic-gate *fdp = fd; 725*7c478bd9Sstevel@tonic-gate return (htons(sin.sin_port)); 726*7c478bd9Sstevel@tonic-gate } 727*7c478bd9Sstevel@tonic-gate 728*7c478bd9Sstevel@tonic-gate void 729*7c478bd9Sstevel@tonic-gate usage(void) 730*7c478bd9Sstevel@tonic-gate { 731*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Usage: on [-i|-n] [-d] machine cmd [args]...\n"); 732*7c478bd9Sstevel@tonic-gate exit(1); 733*7c478bd9Sstevel@tonic-gate } 734*7c478bd9Sstevel@tonic-gate 735*7c478bd9Sstevel@tonic-gate /* 736*7c478bd9Sstevel@tonic-gate * SETPROCTITLE -- set the title of this process for "ps" 737*7c478bd9Sstevel@tonic-gate * 738*7c478bd9Sstevel@tonic-gate * Does nothing if there were not enough arguments on the command 739*7c478bd9Sstevel@tonic-gate * line for the information. 740*7c478bd9Sstevel@tonic-gate * 741*7c478bd9Sstevel@tonic-gate * Side Effects: 742*7c478bd9Sstevel@tonic-gate * Clobbers argv[] of our main procedure. 743*7c478bd9Sstevel@tonic-gate */ 744*7c478bd9Sstevel@tonic-gate void 745*7c478bd9Sstevel@tonic-gate setproctitle(user, host) 746*7c478bd9Sstevel@tonic-gate char *user, *host; 747*7c478bd9Sstevel@tonic-gate { 748*7c478bd9Sstevel@tonic-gate register char *tohere; 749*7c478bd9Sstevel@tonic-gate 750*7c478bd9Sstevel@tonic-gate tohere = Argv[0]; 751*7c478bd9Sstevel@tonic-gate if ((int)LastArgv == (int)((char *)NULL) || 752*7c478bd9Sstevel@tonic-gate (int)(strlen(user) + strlen(host)+3) > (int)(LastArgv - tohere)) 753*7c478bd9Sstevel@tonic-gate return; 754*7c478bd9Sstevel@tonic-gate *tohere++ = '-'; /* So ps prints (rpc.rexd) */ 755*7c478bd9Sstevel@tonic-gate sprintf(tohere, "%s@%s", user, host); 756*7c478bd9Sstevel@tonic-gate while (*tohere++) /* Skip to end of printf output */ 757*7c478bd9Sstevel@tonic-gate ; 758*7c478bd9Sstevel@tonic-gate while (tohere < LastArgv) /* Avoid confusing ps */ 759*7c478bd9Sstevel@tonic-gate *tohere++ = ' '; 760*7c478bd9Sstevel@tonic-gate } 761