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, 122 from_server_p, 0); 123 } 124 125 # else /* ! START_RSH_WITH_POPEN_RW */ 126 127 void 128 start_rsh_server (cvsroot_t *root, struct buffer **to_server_p, 129 struct buffer **from_server_p) 130 { 131 /* If you're working through firewalls, you can set the 132 CVS_RSH environment variable to a script which uses rsh to 133 invoke another rsh on a proxy machine. */ 134 char *cvs_rsh = (root->cvs_rsh != NULL 135 ? root->cvs_rsh : getenv ("CVS_RSH")); 136 char *cvs_server = (root->cvs_server != NULL 137 ? root->cvs_server : getenv ("CVS_SERVER")); 138 char *command; 139 int tofd, fromfd; 140 int child_pid; 141 142 if (!cvs_rsh) 143 cvs_rsh = RSH_DFLT; 144 if (!cvs_server) 145 cvs_server = "cvs"; 146 147 /* Pass the command to rsh as a single string. This shouldn't 148 * affect most rsh servers at all, and will pacify some buggy 149 * versions of rsh that grab switches out of the middle of the 150 * command (they're calling the GNU getopt routines incorrectly). 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 */ 157 command = Xasprintf ("%s server", cvs_server); 158 159 { 160 char *argv[10]; 161 char **p = argv; 162 163 *p++ = cvs_rsh; 164 165 /* If the login names differ between client and server 166 * pass it on to rsh. 167 */ 168 if (root->username != NULL) 169 { 170 *p++ = "-l"; 171 *p++ = root->username; 172 } 173 174 *p++ = root->hostname; 175 *p++ = command; 176 *p++ = NULL; 177 178 if (trace) 179 { 180 int i; 181 182 fprintf (stderr, " -> Starting server: "); 183 for (i = 0; argv[i]; i++) 184 fprintf (stderr, "%s ", argv[i]); 185 putc ('\n', stderr); 186 } 187 child_pid = piped_child (argv, &tofd, &fromfd, true); 188 189 if (child_pid < 0) 190 error (1, errno, "cannot start server via rsh"); 191 } 192 free (command); 193 194 make_bufs_from_fds (tofd, fromfd, child_pid, root, to_server_p, 195 from_server_p, 0); 196 } 197 198 # endif /* START_RSH_WITH_POPEN_RW */ 199 200 #endif /* NO_EXT_METHOD */ 201 202 #endif /* CLIENT_SUPPORT */ 203