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