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