Annotation of src/usr.bin/rdist/rshrcmd.c, Revision 1.2
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 */