Annotation of src/usr.bin/rdist/rshrcmd.c, Revision 1.1
1.1 ! dm 1:
! 2: /*
! 3: * This is an rcmd() replacement originally by
! 4: * Chris Siebenmann <cks@utcc.utoronto.ca>.
! 5: */
! 6:
! 7: #ifndef lint
! 8: static char RCSid[] =
! 9: "$Id: rshrcmd.c,v 1.7 1995/12/12 00:20:55 mcooper Exp $";
! 10: #endif
! 11:
! 12: #include "defs.h"
! 13:
! 14: #if !defined(DIRECT_RCMD)
! 15:
! 16: #include <sys/types.h>
! 17: #include <sys/socket.h>
! 18: #include <sys/wait.h>
! 19: #include <signal.h>
! 20: #include <errno.h>
! 21: #include <netdb.h>
! 22: #include <stdio.h>
! 23:
! 24: /*
! 25: * This is a replacement rcmd() function that uses the rsh(1c)
! 26: * program in place of a direct rcmd() function call so as to
! 27: * avoid having to be root.
! 28: */
! 29: rshrcmd(ahost, port, luser, ruser, cmd, fd2p)
! 30: char **ahost;
! 31: u_short port;
! 32: char *luser, *ruser, *cmd;
! 33: int *fd2p;
! 34: {
! 35: int cpid;
! 36: struct hostent *hp;
! 37: int sp[2];
! 38:
! 39: /* insure that we are indeed being used as we thought. */
! 40: if (fd2p != 0)
! 41: return -1;
! 42: /* validate remote hostname. */
! 43: hp = gethostbyname(*ahost);
! 44: if (hp == 0) {
! 45: error("%s: unknown host", *ahost);
! 46: return -1;
! 47: }
! 48: /* *ahost = hp->h_name; /* This makes me nervous. */
! 49:
! 50: /* get a socketpair we'll use for stdin and stdout. */
! 51: if (getsocketpair(AF_UNIX, SOCK_STREAM, 0, sp) < 0) {
! 52: error("socketpair(AF_UNIX, SOCK_STREAM, 0) failed: %s.",
! 53: SYSERR);
! 54: return -1;
! 55: }
! 56:
! 57: cpid = fork();
! 58: if (cpid < 0) {
! 59: error("fork failed: %s.", SYSERR);
! 60: return -1; /* error. */
! 61: }
! 62: if (cpid == 0) {
! 63: /* child. we use sp[1] to be stdin/stdout, and close
! 64: sp[0]. */
! 65: (void) close(sp[0]);
! 66: if (dup2(sp[1], 0) < 0 || dup2(0,1) < 0 || dup2(0, 2) < 0) {
! 67: error("dup2 failed: %s.", SYSERR);
! 68: _exit(255);
! 69: }
! 70: /* fork again to lose parent. */
! 71: cpid = fork();
! 72: if (cpid < 0) {
! 73: error("fork to lose parent failed: %s.", SYSERR);
! 74: _exit(255);
! 75: }
! 76: if (cpid > 0)
! 77: _exit(0);
! 78: /* in grandchild here. */
! 79:
! 80: /*
! 81: * If we are rdist'ing to "localhost" as the same user
! 82: * as we are, then avoid running remote shell for efficiency.
! 83: */
! 84: if (strcmp(*ahost, "localhost") == 0 &&
! 85: strcmp(luser, ruser) == 0) {
! 86: execlp(_PATH_BSHELL, xbasename(_PATH_BSHELL), "-c",
! 87: cmd, (char *) NULL);
! 88: error("execlp %s failed: %s.", _PATH_BSHELL, SYSERR);
! 89: } else {
! 90: execlp(path_remsh, xbasename(path_remsh),
! 91: *ahost, "-l", ruser, cmd, (char *) NULL);
! 92: error("execlp %s failed: %s.", path_remsh, SYSERR);
! 93: }
! 94: _exit(255);
! 95: }
! 96: if (cpid > 0) {
! 97: /* parent. close sp[1], return sp[0]. */
! 98: (void) close(sp[1]);
! 99: /* reap child. */
! 100: (void) wait(0);
! 101: return sp[0];
! 102: }
! 103: /*NOTREACHED*/
! 104: }
! 105:
! 106: #endif /* !DIRECT_RCMD */