Sweep-fix comparing pointers with 0 (and assigning 0 to pointers).
[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  */
8
9 #include <sys/types.h>
10 #include <sys/socket.h>
11 #include <sys/wait.h>
12
13 #include <netdb.h>
14 #include <signal.h>
15
16 #include "defs.h"
17
18 #if     !defined(DIRECT_RCMD)
19
20 static char *
21 xbasename(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(char **ahost, u_short port, char *luser, char *ruser, char *cmd, int *fd2p)
39 {
40         int             cpid, sp[2];
41         struct hostent  *hp;
42
43         /* insure that we are indeed being used as we thought. */
44         if (fd2p != NULL)
45                 return -1;
46         /* validate remote hostname. */
47         hp = gethostbyname(*ahost);
48         if (hp == NULL) {
49                 error("%s: unknown host", *ahost);
50                 return -1;
51         }
52
53         /* get a socketpair we'll use for stdin and stdout. */
54         if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) < 0) {
55                 error("socketpair(AF_UNIX, SOCK_STREAM, 0) failed: %s.", 
56                       strerror(errno));
57                 return -1;
58         }
59
60         cpid = fork();
61         if (cpid < 0) {
62                 error("fork failed: %s.", strerror(errno));
63                 return -1;      /* error. */
64         }
65         if (cpid == 0) {
66                 /* child. we use sp[1] to be stdin/stdout, and close
67                    sp[0]. */
68                 close(sp[0]);
69                 if (dup2(sp[1], 0) < 0 || dup2(0,1) < 0) {
70                         error("dup2 failed: %s.", strerror(errno));
71                         _exit(255);
72                 }
73                 /* fork again to lose parent. */
74                 cpid = fork();
75                 if (cpid < 0) {
76                         error("fork to lose parent failed: %s.", strerror(errno));
77                         _exit(255);
78                 }
79                 if (cpid > 0)
80                         _exit(0);
81                 /* in grandchild here. */
82
83                 /*
84                  * If we are rdist'ing to "localhost" as the same user
85                  * as we are, then avoid running remote shell for efficiency.
86                  */
87                 if (strcmp(*ahost, "localhost") == 0 &&
88                     strcmp(luser, ruser) == 0) {
89                         execlp(_PATH_BSHELL, xbasename(_PATH_BSHELL), "-c",
90                                cmd, NULL);
91                         error("execlp %s failed: %s.", _PATH_BSHELL, strerror(errno));
92                 } else {
93                         execlp(path_rsh, xbasename(path_rsh), 
94                                *ahost, "-l", ruser, cmd, NULL);
95                         error("execlp %s failed: %s.", path_rsh,
96                                 strerror(errno));
97                 }
98                 _exit(255);
99         }
100         if (cpid > 0) {
101                 /* parent. close sp[1], return sp[0]. */
102                 close(sp[1]);
103                 /* reap child. */
104                 wait(0);
105                 return sp[0];
106         }
107         /*NOTREACHED*/
108         return (-1);
109 }
110
111 #endif  /* !DIRECT_RCMD */