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