summaryrefslogtreecommitdiff
path: root/usr/src/cmd/rexd/on.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/rexd/on.c')
-rw-r--r--usr/src/cmd/rexd/on.c762
1 files changed, 0 insertions, 762 deletions
diff --git a/usr/src/cmd/rexd/on.c b/usr/src/cmd/rexd/on.c
deleted file mode 100644
index f436e71126..0000000000
--- a/usr/src/cmd/rexd/on.c
+++ /dev/null
@@ -1,762 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * on - user interface program for remote execution service
- *
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#define BSD_COMP
-
-#include <ctype.h>
-#include <errno.h>
-#include <netdb.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <netinet/in.h>
-#include <rpc/rpc.h>
-#include <rpc/clnt_soc.h>
-#include <rpc/key_prot.h>
-#include <sys/fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-
-
-#include <sys/ttold.h>
-
-
-#include "rex.h"
-
-#include <stropts.h>
-#include <sys/stream.h>
-#include <sys/ttcompat.h>
-
-
-#define bcmp(b1, b2, len) memcmp(b1, b2, len)
-#define bzero(b, len) memset(b, '\0', len)
-#define bcopy(b1, b2, len) memcpy(b2, b1, len)
-
-#define CommandName "on" /* given as argv[0] */
-#define AltCommandName "dbon"
-
-extern int errno;
-
-/*
- * Note - the following must be long enough for at least two portmap
- * timeouts on the other side.
- */
-struct timeval LongTimeout = { 123, 0 };
-struct timeval testtimeout = { 5, 0 };
-
-int Debug = 0; /* print extra debugging information */
-int Only2 = 0; /* stdout and stderr are the same */
-int Interactive = 0; /* use a pty on server */
-int NoInput = 0; /* don't read standard input */
-int child = 0; /* pid of the executed process */
-int ChildDied = 0; /* true when above is valid */
-int HasHelper = 0; /* must kill helpers (interactive mode) */
-
-int InOut; /* socket for stdin/stdout */
-int Err; /* socket for stderr */
-
-struct sgttyb OldFlags; /* saved tty flags */
-struct sgttyb NewFlags; /* for stop/continue job control */
-CLIENT *Client; /* RPC client handle */
-struct rex_ttysize WindowSize; /* saved window size */
-
-static int Argc;
-static char **Argv; /* saved argument vector (for ps) */
-static char *LastArgv; /* saved end-of-argument vector */
-
-void usage(void);
-void Die(int stat);
-void doaccept(int *fdp);
-u_short makeport(int *fdp);
-
-
-/*
- * window change handler - propagate to remote server
- */
-void
-sigwinch(int junk)
-{
- struct winsize newsize; /* the modern way to get row and col */
- struct rex_ttysize size; /* the old way no body */
- /* bothered to change */
- enum clnt_stat clstat;
-
- ioctl(0, TIOCGWINSZ, &newsize);
-
- /*
- * compensate for the struct change
- */
- size.ts_lines = (int)newsize.ws_row; /* typecast important! */
- size.ts_cols = (int)newsize.ws_col;
-
- if (bcmp(&size, &WindowSize, sizeof (size)) == 0)
- return;
-
- WindowSize = size;
- if (clstat = clnt_call(Client, REXPROC_WINCH,
- xdr_rex_ttysize, (caddr_t)&size, xdr_void,
- NULL, LongTimeout)) {
- fprintf(stderr, "on (size): ");
- clnt_perrno(clstat);
- fprintf(stderr, "\r\n");
- }
-}
-
-/*
- * signal handler - propagate to remote server
- */
-void
-sendsig(int sig)
-{
- enum clnt_stat clstat;
-
- if (clstat = clnt_call(Client, REXPROC_SIGNAL,
- xdr_int, (caddr_t) &sig, xdr_void,
- NULL, LongTimeout)) {
- fprintf(stderr, "on (signal): ");
- clnt_perrno(clstat);
- fprintf(stderr, "\r\n");
- }
-}
-
-
-void
-cont(int junk)
-{
- /*
- * Put tty modes back the way they were and tell the rexd server
- * to send the command a SIGCONT signal.
- */
- if (Interactive) {
- ioctl(0, TIOCSETN, &NewFlags);
- (void) send(InOut, "", 1, MSG_OOB);
- }
-}
-
-/*
- * oob -- called when the command invoked by the rexd server is stopped
- * with a SIGTSTP or SIGSTOP signal.
- */
-void
-oob(int junk)
-{
- int atmark;
- char waste[BUFSIZ], mark;
-
- for (;;) {
- if (ioctl(InOut, SIOCATMARK, &atmark) < 0) {
- perror("ioctl");
- break;
- }
- if (atmark)
- break;
- (void) read(InOut, waste, sizeof (waste));
- }
- (void) recv(InOut, &mark, 1, MSG_OOB);
- /*
- * Reset tty modes to something sane and stop myself
- */
- if (Interactive) {
- ioctl(0, TIOCSETN, &OldFlags);
- printf("\r\n");
- }
- kill(getpid(), SIGSTOP);
-}
-
-
-
-int
-main(int argc, char **argv)
-{
- struct winsize newsize; /* the modern way to get row and col */
- char *rhost, **cmdp;
- char curdir[MAXPATHLEN];
- char wdhost[MAXHOSTNAMELEN];
- char fsname[MAXPATHLEN];
- char dirwithin[MAXPATHLEN];
- struct rex_start rst;
- struct rex_result result;
- extern char **environ;
- enum clnt_stat clstat;
- struct hostent *hp;
- struct sockaddr_in server_addr;
- int sock = RPC_ANYSOCK;
- fd_set selmask, zmask, remmask;
- int nfds, cc;
- char *chi, *cho;
- int trying_authdes;
- char netname[MAXNETNAMELEN+1];
- char hostname[MAXHOSTNAMELEN+1];
- char publickey[HEXKEYBYTES+1];
- int i;
- char *domain;
- static char buf[4096];
-
- /*
- * we check the invoked command name to see if it should
- * really be a host name.
- */
- if ((rhost = strrchr(argv[0], '/')) == NULL) {
- rhost = argv[0];
- } else {
- rhost++;
- }
-
- /*
- * argv start and extent for setproctitle()
- */
- Argc = argc;
- Argv = argv;
- if (argc > 0)
- LastArgv = argv[argc-1] + strlen(argv[argc-1]);
- else
- LastArgv = NULL;
-
- while (argc > 1 && argv[1][0] == '-') {
- switch (argv[1][1]) {
- case 'd': Debug = 1;
- break;
- case 'i': Interactive = 1;
- break;
- case 'n': NoInput = 1;
- break;
- default:
- printf("Unknown option %s\n", argv[1]);
- }
- argv++;
- argc--;
- }
-
- if (strcmp(rhost, CommandName) && strcmp(rhost, AltCommandName)) {
- cmdp = &argv[1];
- Interactive = 1;
- } else {
- if (argc < 2)
- usage();
- rhost = argv[1];
- cmdp = &argv[2];
- }
-
- /*
- * Can only have one of these
- */
- if (Interactive && NoInput)
- usage();
-
- if ((hp = gethostbyname(rhost)) == NULL) {
- fprintf(stderr, "on: unknown host %s\n", rhost);
- exit(1);
- }
-
- bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr, hp->h_length);
- server_addr.sin_family = AF_INET;
- server_addr.sin_port = 0; /* use pmapper */
-
- if (Debug)
- printf("Got the host named %s (%s)\n",
- rhost, inet_ntoa(server_addr.sin_addr));
- trying_authdes = 1;
-
-try_auth_unix:
- sock = RPC_ANYSOCK;
-
- if (Debug)
- printf("clnt_create: Server_Addr %u Prog %d Vers %d Sock %d\n",
- &server_addr, REXPROG, REXVERS, sock);
-
- if ((Client = clnttcp_create(&server_addr, REXPROG, REXVERS, &sock,
- 0, 0)) == NULL) {
- fprintf(stderr, "on: cannot connect to server on %s\n",
- rhost);
- clnt_pcreateerror("on:");
- exit(1);
- }
-
- if (Debug)
- printf("TCP RPC connection created\n");
-
- if (trying_authdes) {
- yp_get_default_domain(&domain);
-
- cho = hostname;
- *cho = 0;
- chi = hp->h_name;
-
- for (i = 0; (*chi && (i < MAXHOSTNAMELEN)); i++)
- {
- if (isupper(*chi))
- *cho = tolower(*chi);
- else
- *cho = *chi;
- cho++;
- chi++;
- }
- *cho = 0;
-
- if (domain != NULL) {
- if (host2netname(netname, hostname, domain) == 0) {
- trying_authdes = 0;
- if (Debug)
- printf("host2netname failed %s\n",
- hp->h_name);
- }
- /* #ifdef NOWAY */
- else {
-
- if (getpublickey(netname, publickey) == 0) {
- trying_authdes = 0;
- cho = strchr(hostname, '.');
-
- if (cho) {
- *cho = 0;
-
- if (!host2netname(netname,
- hostname,
- domain)) {
- if (Debug)
- printf("host2netname failed %s\n", hp->h_name);
- } else {
- if (getpublickey(
- netname,
- publickey) != 0)
- trying_authdes = 1;
- }
- }
- }
- }
- } else {
- trying_authdes = 0;
- if (Debug)
- printf("yp_get_default_domain failed \n");
- }
- }
-
- if (trying_authdes) {
- Client->cl_auth = (AUTH *)authdes_create(netname, 60*60,
- &server_addr, NULL);
-
- if (Client->cl_auth == NULL) {
-
- if (Debug)
- printf("authdes_create failed %s\n", netname);
- trying_authdes = 0;
- }
- }
-
-
- if (trying_authdes == 0)
- if ((Client->cl_auth = authsys_create_default()) == NULL) {
- clnt_destroy(Client);
- fprintf(stderr,"on: can't create authunix structure.\n");
- exit(1);
- }
-
-
- /*
- * Now that we have created the TCP connection, we do some
- * work while the server daemon is being swapped in.
- */
- if (getcwd(curdir, MAXPATHLEN) == (char *)NULL) {
- fprintf(stderr, "on: can't find . (%s)\n", curdir);
- exit(1);
- }
-
- if (findmount(curdir, wdhost, fsname, dirwithin) == 0) {
-
- if (Debug) {
- fprintf(stderr,
- "findmount failed: curdir %s\twdhost %s\t",
- curdir, wdhost);
- fprintf(stderr, "fsname %s\tdirwithin %s\n",
- fsname, dirwithin);
- }
-
- fprintf(stderr, "on: can't locate mount point for %s (%s)\n",
- curdir, dirwithin);
- exit(1);
- }
-
- if (Debug) {
- printf("findmount suceeds: cwd= %s, wd host %s, fs %s,",
- curdir, wdhost, fsname);
- printf("dir within %s\n", dirwithin);
- }
-
- Only2 = samefd(1, 2);
-
- rst.rst_cmd = (void *)(cmdp);
- rst.rst_host = (void *)wdhost;
- rst.rst_fsname = (void *)fsname;
- rst.rst_dirwithin = (void *)dirwithin;
- rst.rst_env = (void *)environ;
- rst.rst_port0 = makeport(&InOut);
- rst.rst_port1 = rst.rst_port0; /* same port for stdin */
- rst.rst_flags = 0;
-
- if (Debug)
- printf("before Interactive flags\n");
-
- if (Interactive) {
- rst.rst_flags |= REX_INTERACTIVE;
- ioctl(0, TIOCGETP, &OldFlags);
- NewFlags = OldFlags;
- NewFlags.sg_flags |= (u_int)RAW;
- NewFlags.sg_flags &= (u_int)~ECHO;
- ioctl(0, TIOCSETN, &NewFlags);
- }
-
- if (Only2) {
- rst.rst_port2 = rst.rst_port1;
- } else {
- rst.rst_port2 = makeport(&Err);
- }
-
- if (Debug)
- printf("before client call REXPROC_START\n");
-
- (void) memset(&result, '\0', sizeof(result));
-
- if (clstat = clnt_call(Client, REXPROC_START,
- xdr_rex_start, (caddr_t)&rst,
- xdr_rex_result, (caddr_t)&result, LongTimeout)) {
-
- if (Debug)
- printf("Client call failed for REXPROC_START\r\n");
-
- if (trying_authdes) {
- auth_destroy(Client->cl_auth);
- clnt_destroy(Client);
- trying_authdes = 0;
- if (Interactive)
- ioctl(0, TIOCSETN, &OldFlags);
- goto try_auth_unix;
- } else {
- fprintf(stderr, "on %s: ", rhost);
- clnt_perrno(clstat);
- fprintf(stderr, "\n");
- Die(1);
- }
- }
-
- if (result.rlt_stat != 0) {
- fprintf(stderr, "on %s: %s\n\r", rhost, result.rlt_message);
- Die(1);
- }
-
- clnt_freeres(Client, xdr_rex_result, (caddr_t)&result);
-
- if (Debug)
- printf("Client call suceeded for REXPROC_START\r\n");
-
- if (Interactive) {
- /*
- * Pass the tty modes along to the server
- */
- struct rex_ttymode mode;
- int err;
-
- mode.basic.sg_ispeed = OldFlags.sg_ispeed;
- mode.basic.sg_ospeed = OldFlags.sg_ospeed;
- mode.basic.sg_erase = OldFlags.sg_erase;
- mode.basic.sg_kill = OldFlags.sg_kill;
- mode.basic.sg_flags = (short) (OldFlags.sg_flags & 0xFFFF);
- err = (ioctl(0, TIOCGETC, &mode.more) < 0 ||
- ioctl(0, TIOCGLTC, &mode.yetmore) < 0 ||
- ioctl(0, TIOCLGET, &mode.andmore) < 0);
- if (Debug)
- printf("Before clnt_call(REXPROC_MODES) err=%d\n", err);
-
- if (!err && (clstat = clnt_call(Client, REXPROC_MODES,
- xdr_rex_ttymode, (caddr_t)&mode,
- xdr_void, NULL, LongTimeout))) {
-
- fprintf(stderr, "on (modes) %s: ", rhost);
- clnt_perrno(clstat);
- fprintf(stderr, "\r\n");
- }
-
- err = ioctl(0, TIOCGWINSZ, &newsize) < 0;
- /* typecast important in following lines */
- WindowSize.ts_lines = (int)newsize.ws_row;
- WindowSize.ts_cols = (int)newsize.ws_col;
-
- if (Debug)
- printf("Before client call REXPROC_WINCH\n");
-
- if (!err && (clstat = clnt_call(Client, REXPROC_WINCH,
- xdr_rex_ttysize, (caddr_t)&WindowSize,
- xdr_void, NULL, LongTimeout))) {
-
- fprintf(stderr, "on (size) %s: ", rhost);
- clnt_perrno(clstat);
- fprintf(stderr, "\r\n");
- }
-
- sigset(SIGWINCH, sigwinch);
- sigset(SIGINT, sendsig);
- sigset(SIGQUIT, sendsig);
- sigset(SIGTERM, sendsig);
- }
- sigset(SIGCONT, cont);
- sigset(SIGURG, oob);
- doaccept(&InOut);
- (void) fcntl(InOut, F_SETOWN, getpid());
- FD_ZERO(&remmask);
- FD_SET(InOut, &remmask);
- if (Debug)
- printf("accept on stdout\r\n");
-
- if (!Only2) {
-
- doaccept(&Err);
- shutdown(Err, 1); /* 1=> further sends disallowed */
- if (Debug)
- printf("accept on stderr\r\n");
- FD_SET(Err, &remmask);
- }
-
- FD_ZERO(&zmask);
- if (NoInput) {
-
- /*
- * no input - simulate end-of-file instead
- */
- shutdown(InOut, 1); /* 1=> further sends disallowed */
- } else {
- /*
- * set up to read standard input, send to remote
- */
- FD_SET(0, &zmask);
- }
-
- FD_ZERO(&selmask);
- while (FD_ISSET(InOut, &remmask) || FD_ISSET(Err, &remmask)) {
- if (FD_ISSET(InOut, &remmask))
- FD_SET(InOut, &selmask);
- else
- FD_CLR(InOut, &selmask);
- if (FD_ISSET(Err, &remmask))
- FD_SET(Err, &selmask);
- else
- FD_CLR(Err, &selmask);
- if (FD_ISSET(0, &zmask))
- FD_SET(0, &selmask);
- else
- FD_CLR(0, &selmask);
- nfds = select(FD_SETSIZE, &selmask, (fd_set *) 0, (fd_set *) 0,
- (struct timeval *) 0);
-
-
- if (nfds <= 0) {
- if (errno == EINTR) continue;
- perror("on: select");
- Die(1);
- }
- if (FD_ISSET(InOut, &selmask)) {
-
- cc = read(InOut, buf, sizeof buf);
- if (cc > 0)
- write(1, buf, cc);
- else
- FD_CLR(InOut, &remmask);
- }
-
- if (!Only2 && FD_ISSET(Err, &selmask)) {
-
- cc = read(Err, buf, sizeof buf);
- if (cc > 0)
- write(2, buf, cc);
- else
- FD_CLR(Err, &remmask);
- }
-
- if (!NoInput && FD_ISSET(0, &selmask)) {
-
- cc = read(0, buf, sizeof buf);
- if (cc > 0)
- write(InOut, buf, cc);
- else {
- /*
- * End of standard input - shutdown outgoing
- * direction of the TCP connection.
- */
- if (Debug)
- printf("Got EOF - shutting down connection\n");
- FD_CLR(0, &zmask);
- shutdown(InOut, 1); /* further sends disallowed */
- }
- }
- }
-
- close(InOut);
- if (!Only2)
- close(Err);
-
- (void) memset(&result, '\0', sizeof(result));
-
- if (clstat = clnt_call(Client, REXPROC_WAIT,
- xdr_void, 0, xdr_rex_result, (caddr_t)&result,
- LongTimeout)) {
-
- fprintf(stderr, "on: ");
- clnt_perrno(clstat);
- fprintf(stderr, "\r\n");
- Die(1);
- }
- Die(result.rlt_stat);
- return (0); /* Should never get here. */
-}
-
-/*
- * like exit, but resets the terminal state first
- */
-void
-Die(int stat)
-
-{
- if (Interactive) {
- ioctl(0, TIOCSETN, &OldFlags);
- printf("\r\n");
- }
- exit(stat);
-}
-
-
-void
-remstop()
-
-{
- Die(23);
-}
-
-/*
- * returns true if we can safely say that the two file descriptors
- * are the "same" (both are same file).
- */
-int
-samefd(a, b)
-{
- struct stat astat, bstat;
-
- if (fstat(a, &astat) || fstat(b, &bstat))
- return (0);
- if (astat.st_ino == 0 || bstat.st_ino == 0)
- return (0);
- return (!bcmp(&astat, &bstat, sizeof (astat)));
-}
-
-
-/*
- * accept the incoming connection on the given
- * file descriptor, and return the new file descritpor
- */
-void
-doaccept(fdp)
- int *fdp;
-{
- int fd;
-
- fd = accept(*fdp, 0, 0);
-
- if (fd < 0) {
- perror("accept");
- remstop();
- }
- close(*fdp);
- *fdp = fd;
-}
-
-/*
- * create a socket, and return its the port number.
- */
-u_short
-makeport(fdp)
- int *fdp;
-{
- struct sockaddr_in sin;
- socklen_t len = (socklen_t)sizeof (sin);
- int fd;
-
- fd = socket(AF_INET, SOCK_STREAM, 0);
-
- if (fd < 0) {
- perror("socket");
- exit(1);
- }
-
- bzero((char *)&sin, sizeof (sin));
- sin.sin_family = AF_INET;
- bind(fd, (struct sockaddr *)&sin, sizeof (sin));
- getsockname(fd, (struct sockaddr *)&sin, &len);
- listen(fd, 1);
- *fdp = fd;
- return (htons(sin.sin_port));
-}
-
-void
-usage(void)
-{
- fprintf(stderr, "Usage: on [-i|-n] [-d] machine cmd [args]...\n");
- exit(1);
-}
-
-/*
- * SETPROCTITLE -- set the title of this process for "ps"
- *
- * Does nothing if there were not enough arguments on the command
- * line for the information.
- *
- * Side Effects:
- * Clobbers argv[] of our main procedure.
- */
-void
-setproctitle(user, host)
- char *user, *host;
-{
- register char *tohere;
-
- tohere = Argv[0];
- if ((int)LastArgv == (int)((char *)NULL) ||
- (int)(strlen(user) + strlen(host)+3) > (int)(LastArgv - tohere))
- return;
- *tohere++ = '-'; /* So ps prints (rpc.rexd) */
- sprintf(tohere, "%s@%s", user, host);
- while (*tohere++) /* Skip to end of printf output */
- ;
- while (tohere < LastArgv) /* Avoid confusing ps */
- *tohere++ = ' ';
-}