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