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