xref: /csrg-svn/lib/libcompat/4.3/rexec.c (revision 61241)
121389Sdist /*
2*61241Sbostic  * Copyright (c) 1980, 1993
3*61241Sbostic  *	The Regents of the University of California.  All rights reserved.
433679Sbostic  *
542629Sbostic  * %sccs.include.redist.c%
621389Sdist  */
721389Sdist 
826626Sdonn #if defined(LIBC_SCCS) && !defined(lint)
9*61241Sbostic static char sccsid[] = "@(#)rexec.c	8.1 (Berkeley) 06/04/93";
1033679Sbostic #endif /* LIBC_SCCS and not lint */
115925Smckusick 
125925Smckusick #include <sys/types.h>
135925Smckusick #include <sys/socket.h>
149191Ssam 
159191Ssam #include <netinet/in.h>
169191Ssam 
179191Ssam #include <stdio.h>
189191Ssam #include <netdb.h>
196421Sroot #include <errno.h>
205925Smckusick 
216421Sroot extern	errno;
2232496Sbostic char	*index();
236421Sroot int	rexecoptions;
246421Sroot char	*getpass(), *getlogin();
255925Smckusick 
rexec(ahost,rport,name,pass,cmd,fd2p)266421Sroot rexec(ahost, rport, name, pass, cmd, fd2p)
276421Sroot 	char **ahost;
286421Sroot 	int rport;
296421Sroot 	char *name, *pass, *cmd;
306421Sroot 	int *fd2p;
315925Smckusick {
3236503Sbostic 	struct sockaddr_in sin, sin2, from;
3336503Sbostic 	struct hostent *hp;
3436503Sbostic 	u_short port;
359191Ssam 	int s, timo = 1, s3;
366421Sroot 	char c;
375925Smckusick 
389191Ssam 	hp = gethostbyname(*ahost);
399191Ssam 	if (hp == 0) {
4035786Sbostic 		herror(*ahost);
415925Smckusick 		return (-1);
425925Smckusick 	}
439191Ssam 	*ahost = hp->h_name;
449191Ssam 	ruserpass(hp->h_name, &name, &pass);
456421Sroot retry:
4614675Ssam 	s = socket(AF_INET, SOCK_STREAM, 0);
479191Ssam 	if (s < 0) {
489191Ssam 		perror("rexec: socket");
495925Smckusick 		return (-1);
509191Ssam 	}
519191Ssam 	sin.sin_family = hp->h_addrtype;
526421Sroot 	sin.sin_port = rport;
539191Ssam 	bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
5446631Sbostic 	if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
556421Sroot 		if (errno == ECONNREFUSED && timo <= 16) {
566421Sroot 			(void) close(s);
576421Sroot 			sleep(timo);
586421Sroot 			timo *= 2;
596421Sroot 			goto retry;
606421Sroot 		}
619191Ssam 		perror(hp->h_name);
625925Smckusick 		return (-1);
635925Smckusick 	}
646421Sroot 	if (fd2p == 0) {
656421Sroot 		(void) write(s, "", 1);
666421Sroot 		port = 0;
676421Sroot 	} else {
686421Sroot 		char num[8];
6911624Ssam 		int s2, sin2len;
706421Sroot 
7114675Ssam 		s2 = socket(AF_INET, SOCK_STREAM, 0);
726421Sroot 		if (s2 < 0) {
736421Sroot 			(void) close(s);
746421Sroot 			return (-1);
756421Sroot 		}
769191Ssam 		listen(s2, 1);
7711624Ssam 		sin2len = sizeof (sin2);
7846631Sbostic 		if (getsockname(s2, (struct sockaddr *)&sin2, &sin2len) < 0 ||
7911624Ssam 		  sin2len != sizeof (sin2)) {
8011624Ssam 			perror("getsockname");
8111624Ssam 			(void) close(s2);
8211624Ssam 			goto bad;
8311624Ssam 		}
849191Ssam 		port = ntohs((u_short)sin2.sin_port);
8536503Sbostic 		(void) sprintf(num, "%u", port);
866421Sroot 		(void) write(s, num, strlen(num)+1);
879191Ssam 		{ int len = sizeof (from);
8846631Sbostic 		  s3 = accept(s2, (struct sockaddr *)&from, &len);
899191Ssam 		  close(s2);
909191Ssam 		  if (s3 < 0) {
916421Sroot 			perror("accept");
929191Ssam 			port = 0;
936421Sroot 			goto bad;
949191Ssam 		  }
956421Sroot 		}
969191Ssam 		*fd2p = s3;
976421Sroot 	}
986421Sroot 	(void) write(s, name, strlen(name) + 1);
995925Smckusick 	/* should public key encypt the password here */
1006421Sroot 	(void) write(s, pass, strlen(pass) + 1);
1016421Sroot 	(void) write(s, cmd, strlen(cmd) + 1);
1026421Sroot 	if (read(s, &c, 1) != 1) {
1036421Sroot 		perror(*ahost);
1046421Sroot 		goto bad;
1056421Sroot 	}
1066421Sroot 	if (c != 0) {
1076421Sroot 		while (read(s, &c, 1) == 1) {
1086421Sroot 			(void) write(2, &c, 1);
1096421Sroot 			if (c == '\n')
1106421Sroot 				break;
1116421Sroot 		}
1126421Sroot 		goto bad;
1136421Sroot 	}
1146421Sroot 	return (s);
1156421Sroot bad:
1166421Sroot 	if (port)
1176421Sroot 		(void) close(*fd2p);
1186421Sroot 	(void) close(s);
1196421Sroot 	return (-1);
1205925Smckusick }
121