xref: /dflybsd-src/contrib/cvs-1.12/src/rsh-client.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1*86d7f5d3SJohn Marino /* CVS rsh client stuff.
2*86d7f5d3SJohn Marino 
3*86d7f5d3SJohn Marino    This program is free software; you can redistribute it and/or modify
4*86d7f5d3SJohn Marino    it under the terms of the GNU General Public License as published by
5*86d7f5d3SJohn Marino    the Free Software Foundation; either version 2, or (at your option)
6*86d7f5d3SJohn Marino    any later version.
7*86d7f5d3SJohn Marino 
8*86d7f5d3SJohn Marino    This program is distributed in the hope that it will be useful,
9*86d7f5d3SJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
10*86d7f5d3SJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11*86d7f5d3SJohn Marino    GNU General Public License for more details.  */
12*86d7f5d3SJohn Marino 
13*86d7f5d3SJohn Marino #include <config.h>
14*86d7f5d3SJohn Marino 
15*86d7f5d3SJohn Marino #include "cvs.h"
16*86d7f5d3SJohn Marino #include "buffer.h"
17*86d7f5d3SJohn Marino 
18*86d7f5d3SJohn Marino #ifdef CLIENT_SUPPORT
19*86d7f5d3SJohn Marino 
20*86d7f5d3SJohn Marino #include "rsh-client.h"
21*86d7f5d3SJohn Marino 
22*86d7f5d3SJohn Marino #ifndef NO_EXT_METHOD
23*86d7f5d3SJohn Marino 
24*86d7f5d3SJohn Marino /* Contact the server by starting it with rsh.  */
25*86d7f5d3SJohn Marino 
26*86d7f5d3SJohn Marino /* Right now, we have two different definitions for this function,
27*86d7f5d3SJohn Marino    depending on whether we start the rsh server using popenRW or not.
28*86d7f5d3SJohn Marino    This isn't ideal, and the best thing would probably be to change
29*86d7f5d3SJohn Marino    the OS/2 port to be more like the regular Unix client (i.e., by
30*86d7f5d3SJohn Marino    implementing piped_child)... but I'm doing something else at the
31*86d7f5d3SJohn Marino    moment, and wish to make only one change at a time.  -Karl */
32*86d7f5d3SJohn Marino 
33*86d7f5d3SJohn Marino # ifdef START_RSH_WITH_POPEN_RW
34*86d7f5d3SJohn Marino 
35*86d7f5d3SJohn Marino 
36*86d7f5d3SJohn Marino 
37*86d7f5d3SJohn Marino /* This is actually a crock -- it's OS/2-specific, for no one else
38*86d7f5d3SJohn Marino    uses it.  If I get time, I want to make piped_child and all the
39*86d7f5d3SJohn Marino    other stuff in os2/run.c work right.  In the meantime, this gets us
40*86d7f5d3SJohn Marino    up and running, and that's most important. */
41*86d7f5d3SJohn Marino void
start_rsh_server(cvsroot_t * root,struct buffer ** to_server_p,struct buffer ** from_server_p)42*86d7f5d3SJohn Marino start_rsh_server (cvsroot_t *root, struct buffer **to_server_p,
43*86d7f5d3SJohn Marino                   struct buffer **from_server_p)
44*86d7f5d3SJohn Marino {
45*86d7f5d3SJohn Marino     int pipes[2];
46*86d7f5d3SJohn Marino     int child_pid;
47*86d7f5d3SJohn Marino 
48*86d7f5d3SJohn Marino     /* If you're working through firewalls, you can set the
49*86d7f5d3SJohn Marino        CVS_RSH environment variable to a script which uses rsh to
50*86d7f5d3SJohn Marino        invoke another rsh on a proxy machine.  */
51*86d7f5d3SJohn Marino     char *cvs_rsh = (root->cvs_rsh != NULL
52*86d7f5d3SJohn Marino 		     ? root->cvs_rsh : getenv ("CVS_RSH"));
53*86d7f5d3SJohn Marino     char *cvs_server = (root->cvs_server != NULL
54*86d7f5d3SJohn Marino 			? root->cvs_server : getenv ("CVS_SERVER"));
55*86d7f5d3SJohn Marino     int i = 0;
56*86d7f5d3SJohn Marino     /* This needs to fit "rsh", "-b", "-l", "USER", "host",
57*86d7f5d3SJohn Marino        "cmd (w/ args)", and NULL.  We leave some room to grow. */
58*86d7f5d3SJohn Marino     char *rsh_argv[10];
59*86d7f5d3SJohn Marino 
60*86d7f5d3SJohn Marino     if (!cvs_rsh)
61*86d7f5d3SJohn Marino 	/* People sometimes suggest or assume that this should default
62*86d7f5d3SJohn Marino 	   to "remsh" on systems like HPUX in which that is the
63*86d7f5d3SJohn Marino 	   system-supplied name for the rsh program.  However, that
64*86d7f5d3SJohn Marino 	   causes various problems (keep in mind that systems such as
65*86d7f5d3SJohn Marino 	   HPUX might have non-system-supplied versions of "rsh", like
66*86d7f5d3SJohn Marino 	   a Kerberized one, which one might want to use).  If we
67*86d7f5d3SJohn Marino 	   based the name on what is found in the PATH of the person
68*86d7f5d3SJohn Marino 	   who runs configure, that would make it harder to
69*86d7f5d3SJohn Marino 	   consistently produce the same result in the face of
70*86d7f5d3SJohn Marino 	   different people producing binary distributions.  If we
71*86d7f5d3SJohn Marino 	   based it on "remsh" always being the default for HPUX
72*86d7f5d3SJohn Marino 	   (e.g. based on uname), that might be slightly better but
73*86d7f5d3SJohn Marino 	   would require us to keep track of what the defaults are for
74*86d7f5d3SJohn Marino 	   each system type, and probably would cope poorly if the
75*86d7f5d3SJohn Marino 	   existence of remsh or rsh varies from OS version to OS
76*86d7f5d3SJohn Marino 	   version.  Therefore, it seems best to have the default
77*86d7f5d3SJohn Marino 	   remain "rsh", and tell HPUX users to specify remsh, for
78*86d7f5d3SJohn Marino 	   example in CVS_RSH or other such mechanisms to be devised,
79*86d7f5d3SJohn Marino 	   if that is what they want (the manual already tells them
80*86d7f5d3SJohn Marino 	   that).  */
81*86d7f5d3SJohn Marino 	cvs_rsh = RSH_DFLT;
82*86d7f5d3SJohn Marino     if (!cvs_server)
83*86d7f5d3SJohn Marino 	cvs_server = "cvs";
84*86d7f5d3SJohn Marino 
85*86d7f5d3SJohn Marino     /* The command line starts out with rsh. */
86*86d7f5d3SJohn Marino     rsh_argv[i++] = cvs_rsh;
87*86d7f5d3SJohn Marino 
88*86d7f5d3SJohn Marino #   ifdef RSH_NEEDS_BINARY_FLAG
89*86d7f5d3SJohn Marino     /* "-b" for binary, under OS/2. */
90*86d7f5d3SJohn Marino     rsh_argv[i++] = "-b";
91*86d7f5d3SJohn Marino #   endif /* RSH_NEEDS_BINARY_FLAG */
92*86d7f5d3SJohn Marino 
93*86d7f5d3SJohn Marino     /* Then we strcat more things on the end one by one. */
94*86d7f5d3SJohn Marino     if (root->username != NULL)
95*86d7f5d3SJohn Marino     {
96*86d7f5d3SJohn Marino 	rsh_argv[i++] = "-l";
97*86d7f5d3SJohn Marino 	rsh_argv[i++] = root->username;
98*86d7f5d3SJohn Marino     }
99*86d7f5d3SJohn Marino 
100*86d7f5d3SJohn Marino     rsh_argv[i++] = root->hostname;
101*86d7f5d3SJohn Marino     rsh_argv[i++] = cvs_server;
102*86d7f5d3SJohn Marino     rsh_argv[i++] = "server";
103*86d7f5d3SJohn Marino 
104*86d7f5d3SJohn Marino     /* Mark the end of the arg list. */
105*86d7f5d3SJohn Marino     rsh_argv[i]   = NULL;
106*86d7f5d3SJohn Marino 
107*86d7f5d3SJohn Marino     if (trace)
108*86d7f5d3SJohn Marino     {
109*86d7f5d3SJohn Marino 	fprintf (stderr, " -> Starting server: ");
110*86d7f5d3SJohn Marino 	for (i = 0; rsh_argv[i]; i++)
111*86d7f5d3SJohn Marino 	    fprintf (stderr, "%s ", rsh_argv[i]);
112*86d7f5d3SJohn Marino 	putc ('\n', stderr);
113*86d7f5d3SJohn Marino     }
114*86d7f5d3SJohn Marino 
115*86d7f5d3SJohn Marino     /* Do the deed. */
116*86d7f5d3SJohn Marino     child_pid = popenRW (rsh_argv, pipes);
117*86d7f5d3SJohn Marino     if (child_pid < 0)
118*86d7f5d3SJohn Marino 	error (1, errno, "cannot start server via rsh");
119*86d7f5d3SJohn Marino 
120*86d7f5d3SJohn Marino     /* Give caller the file descriptors in a form it can deal with. */
121*86d7f5d3SJohn Marino     make_bufs_from_fds (pipes[0], pipes[1], child_pid, to_server_p,
122*86d7f5d3SJohn Marino                         from_server_p, 0);
123*86d7f5d3SJohn Marino }
124*86d7f5d3SJohn Marino 
125*86d7f5d3SJohn Marino # else /* ! START_RSH_WITH_POPEN_RW */
126*86d7f5d3SJohn Marino 
127*86d7f5d3SJohn Marino void
start_rsh_server(cvsroot_t * root,struct buffer ** to_server_p,struct buffer ** from_server_p)128*86d7f5d3SJohn Marino start_rsh_server (cvsroot_t *root, struct buffer **to_server_p,
129*86d7f5d3SJohn Marino                   struct buffer **from_server_p)
130*86d7f5d3SJohn Marino {
131*86d7f5d3SJohn Marino     /* If you're working through firewalls, you can set the
132*86d7f5d3SJohn Marino        CVS_RSH environment variable to a script which uses rsh to
133*86d7f5d3SJohn Marino        invoke another rsh on a proxy machine.  */
134*86d7f5d3SJohn Marino     char *cvs_rsh = (root->cvs_rsh != NULL
135*86d7f5d3SJohn Marino 		     ? root->cvs_rsh : getenv ("CVS_RSH"));
136*86d7f5d3SJohn Marino     char *cvs_server = (root->cvs_server != NULL
137*86d7f5d3SJohn Marino 			? root->cvs_server : getenv ("CVS_SERVER"));
138*86d7f5d3SJohn Marino     char *command;
139*86d7f5d3SJohn Marino     int tofd, fromfd;
140*86d7f5d3SJohn Marino     int child_pid;
141*86d7f5d3SJohn Marino 
142*86d7f5d3SJohn Marino     if (!cvs_rsh)
143*86d7f5d3SJohn Marino 	cvs_rsh = RSH_DFLT;
144*86d7f5d3SJohn Marino     if (!cvs_server)
145*86d7f5d3SJohn Marino 	cvs_server = "cvs";
146*86d7f5d3SJohn Marino 
147*86d7f5d3SJohn Marino     /* Pass the command to rsh as a single string.  This shouldn't
148*86d7f5d3SJohn Marino      * affect most rsh servers at all, and will pacify some buggy
149*86d7f5d3SJohn Marino      * versions of rsh that grab switches out of the middle of the
150*86d7f5d3SJohn Marino      * command (they're calling the GNU getopt routines incorrectly).
151*86d7f5d3SJohn Marino      *
152*86d7f5d3SJohn Marino      * If you are running a very old (Nov 3, 1994, before 1.5)
153*86d7f5d3SJohn Marino      * version of the server, you need to make sure that your .bashrc
154*86d7f5d3SJohn Marino      * on the server machine does not set CVSROOT to something
155*86d7f5d3SJohn Marino      * containing a colon (or better yet, upgrade the server).
156*86d7f5d3SJohn Marino      */
157*86d7f5d3SJohn Marino     command = Xasprintf ("%s server", cvs_server);
158*86d7f5d3SJohn Marino 
159*86d7f5d3SJohn Marino     {
160*86d7f5d3SJohn Marino         char *argv[10];
161*86d7f5d3SJohn Marino 	char **p = argv;
162*86d7f5d3SJohn Marino 
163*86d7f5d3SJohn Marino 	*p++ = cvs_rsh;
164*86d7f5d3SJohn Marino 
165*86d7f5d3SJohn Marino 	/* If the login names differ between client and server
166*86d7f5d3SJohn Marino 	 * pass it on to rsh.
167*86d7f5d3SJohn Marino 	 */
168*86d7f5d3SJohn Marino 	if (root->username != NULL)
169*86d7f5d3SJohn Marino 	{
170*86d7f5d3SJohn Marino 	    *p++ = "-l";
171*86d7f5d3SJohn Marino 	    *p++ = root->username;
172*86d7f5d3SJohn Marino 	}
173*86d7f5d3SJohn Marino 
174*86d7f5d3SJohn Marino 	*p++ = root->hostname;
175*86d7f5d3SJohn Marino 	*p++ = command;
176*86d7f5d3SJohn Marino 	*p++ = NULL;
177*86d7f5d3SJohn Marino 
178*86d7f5d3SJohn Marino 	if (trace)
179*86d7f5d3SJohn Marino         {
180*86d7f5d3SJohn Marino 	    int i;
181*86d7f5d3SJohn Marino 
182*86d7f5d3SJohn Marino             fprintf (stderr, " -> Starting server: ");
183*86d7f5d3SJohn Marino 	    for (i = 0; argv[i]; i++)
184*86d7f5d3SJohn Marino 	        fprintf (stderr, "%s ", argv[i]);
185*86d7f5d3SJohn Marino 	    putc ('\n', stderr);
186*86d7f5d3SJohn Marino 	}
187*86d7f5d3SJohn Marino 	child_pid = piped_child (argv, &tofd, &fromfd, true);
188*86d7f5d3SJohn Marino 
189*86d7f5d3SJohn Marino 	if (child_pid < 0)
190*86d7f5d3SJohn Marino 	    error (1, errno, "cannot start server via rsh");
191*86d7f5d3SJohn Marino     }
192*86d7f5d3SJohn Marino     free (command);
193*86d7f5d3SJohn Marino 
194*86d7f5d3SJohn Marino     make_bufs_from_fds (tofd, fromfd, child_pid, root, to_server_p,
195*86d7f5d3SJohn Marino                         from_server_p, 0);
196*86d7f5d3SJohn Marino }
197*86d7f5d3SJohn Marino 
198*86d7f5d3SJohn Marino # endif /* START_RSH_WITH_POPEN_RW */
199*86d7f5d3SJohn Marino 
200*86d7f5d3SJohn Marino #endif /* NO_EXT_METHOD */
201*86d7f5d3SJohn Marino 
202*86d7f5d3SJohn Marino #endif /* CLIENT_SUPPORT */
203