summaryrefslogtreecommitdiff
path: root/scp.c
diff options
context:
space:
mode:
Diffstat (limited to 'scp.c')
-rw-r--r--scp.c155
1 files changed, 68 insertions, 87 deletions
diff --git a/scp.c b/scp.c
index 356d97e63..40cf72963 100644
--- a/scp.c
+++ b/scp.c
@@ -75,7 +75,7 @@
75 */ 75 */
76 76
77#include "includes.h" 77#include "includes.h"
78RCSID("$OpenBSD: scp.c,v 1.40 2000/09/21 11:11:42 markus Exp $"); 78RCSID("$OpenBSD: scp.c,v 1.41 2000/10/11 20:03:27 markus Exp $");
79 79
80#include "ssh.h" 80#include "ssh.h"
81#include "xmalloc.h" 81#include "xmalloc.h"
@@ -102,6 +102,9 @@ void progressmeter(int);
102int getttywidth(void); 102int getttywidth(void);
103int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc); 103int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc);
104 104
105/* setup arguments for the call to ssh */
106void addargs(char *fmt, ...) __attribute__((format(printf, 1, 2)));
107
105/* Time a transfer started. */ 108/* Time a transfer started. */
106static struct timeval start; 109static struct timeval start;
107 110
@@ -114,12 +117,6 @@ off_t totalbytes = 0;
114/* Name of current file being transferred. */ 117/* Name of current file being transferred. */
115char *curfile; 118char *curfile;
116 119
117/* This is set to non-zero if IPv4 is desired. */
118int IPv4 = 0;
119
120/* This is set to non-zero if IPv6 is desired. */
121int IPv6 = 0;
122
123/* This is set to non-zero to enable verbose mode. */ 120/* This is set to non-zero to enable verbose mode. */
124int verbose_mode = 0; 121int verbose_mode = 0;
125 122
@@ -129,23 +126,16 @@ int compress_flag = 0;
129/* This is set to zero if the progressmeter is not desired. */ 126/* This is set to zero if the progressmeter is not desired. */
130int showprogress = 1; 127int showprogress = 1;
131 128
132/* This is set to non-zero if running in batch mode (that is, password
133 and passphrase queries are not allowed). */
134int batchmode = 0;
135
136/* This is set to the cipher type string if given on the command line. */
137char *cipher = NULL;
138
139/* This is set to the RSA authentication identity file name if given on
140 the command line. */
141char *identity = NULL;
142
143/* This is the port to use in contacting the remote site (is non-NULL). */
144char *port = NULL;
145
146/* This is the program to execute for the secured connection. ("ssh" or -S) */ 129/* This is the program to execute for the secured connection. ("ssh" or -S) */
147char *ssh_program = SSH_PROGRAM; 130char *ssh_program = SSH_PROGRAM;
148 131
132/* This is the list of arguments that scp passes to ssh */
133struct {
134 char **list;
135 int num;
136 int nalloc;
137} args;
138
149/* 139/*
150 * This function executes the given command as the specified user on the 140 * This function executes the given command as the specified user on the
151 * given host. This returns < 0 if execution fails, and >= 0 otherwise. This 141 * given host. This returns < 0 if execution fails, and >= 0 otherwise. This
@@ -158,8 +148,8 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
158 int pin[2], pout[2], reserved[2]; 148 int pin[2], pout[2], reserved[2];
159 149
160 if (verbose_mode) 150 if (verbose_mode)
161 fprintf(stderr, "Executing: host %s, user %s, command %s\n", 151 fprintf(stderr, "Executing: program %s host %s, user %s, command %s\n",
162 host, remuser ? remuser : "(unspecified)", cmd); 152 ssh_program, host, remuser ? remuser : "(unspecified)", cmd);
163 153
164 /* 154 /*
165 * Reserve two descriptors so that the real pipes won't get 155 * Reserve two descriptors so that the real pipes won't get
@@ -178,10 +168,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
178 close(reserved[1]); 168 close(reserved[1]);
179 169
180 /* For a child to execute the command on the remote host using ssh. */ 170 /* For a child to execute the command on the remote host using ssh. */
181 if (fork() == 0) { 171 if (fork() == 0) {
182 char *args[100]; /* XXX careful */
183 unsigned int i;
184
185 /* Child. */ 172 /* Child. */
186 close(pin[1]); 173 close(pin[1]);
187 close(pout[0]); 174 close(pout[0]);
@@ -190,41 +177,13 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
190 close(pin[0]); 177 close(pin[0]);
191 close(pout[1]); 178 close(pout[1]);
192 179
193 i = 0; 180 args.list[0] = ssh_program;
194 args[i++] = ssh_program; 181 if (remuser != NULL)
195 args[i++] = "-x"; 182 addargs("-l %s", remuser);
196 args[i++] = "-oFallBackToRsh no"; 183 addargs("%s", host);
197 if (IPv4) 184 addargs("%s", cmd);
198 args[i++] = "-4";
199 if (IPv6)
200 args[i++] = "-6";
201 if (verbose_mode)
202 args[i++] = "-v";
203 if (compress_flag)
204 args[i++] = "-C";
205 if (batchmode)
206 args[i++] = "-oBatchMode yes";
207 if (cipher != NULL) {
208 args[i++] = "-c";
209 args[i++] = cipher;
210 }
211 if (identity != NULL) {
212 args[i++] = "-i";
213 args[i++] = identity;
214 }
215 if (port != NULL) {
216 args[i++] = "-p";
217 args[i++] = port;
218 }
219 if (remuser != NULL) {
220 args[i++] = "-l";
221 args[i++] = remuser;
222 }
223 args[i++] = host;
224 args[i++] = cmd;
225 args[i++] = NULL;
226 185
227 execvp(ssh_program, args); 186 execvp(ssh_program, args.list);
228 perror(ssh_program); 187 perror(ssh_program);
229 exit(1); 188 exit(1);
230 } 189 }
@@ -290,27 +249,45 @@ main(argc, argv)
290 extern char *optarg; 249 extern char *optarg;
291 extern int optind; 250 extern int optind;
292 251
252 args.list = NULL;
253 addargs("ssh"); /* overwritten with ssh_program */
254 addargs("-x");
255 addargs("-oFallBackToRsh no");
256
293 fflag = tflag = 0; 257 fflag = tflag = 0;
294 while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:")) != EOF) 258 while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:o:")) != EOF)
295 switch (ch) { 259 switch (ch) {
296 /* User-visible flags. */ 260 /* User-visible flags. */
297 case '4': 261 case '4':
298 IPv4 = 1;
299 break;
300 case '6': 262 case '6':
301 IPv6 = 1; 263 case 'C':
264 addargs("-%c", ch);
302 break; 265 break;
303 case 'p': 266 case 'o':
304 pflag = 1; 267 case 'c':
268 case 'i':
269 addargs("-%c %s", ch, optarg);
305 break; 270 break;
306 case 'P': 271 case 'P':
307 port = optarg; 272 addargs("-p %s", optarg);
273 break;
274 case 'B':
275 addargs("-o Batchmode yes");
276 break;
277 case 'p':
278 pflag = 1;
308 break; 279 break;
309 case 'r': 280 case 'r':
310 iamrecursive = 1; 281 iamrecursive = 1;
311 break; 282 break;
312 case 'S': 283 case 'S':
313 ssh_program = optarg; 284 ssh_program = xstrdup(optarg);
285 break;
286 case 'v':
287 verbose_mode = 1;
288 break;
289 case 'q':
290 showprogress = 0;
314 break; 291 break;
315 292
316 /* Server options. */ 293 /* Server options. */
@@ -325,24 +302,6 @@ main(argc, argv)
325 iamremote = 1; 302 iamremote = 1;
326 tflag = 1; 303 tflag = 1;
327 break; 304 break;
328 case 'c':
329 cipher = optarg;
330 break;
331 case 'i':
332 identity = optarg;
333 break;
334 case 'v':
335 verbose_mode = 1;
336 break;
337 case 'B':
338 batchmode = 1;
339 break;
340 case 'C':
341 compress_flag = 1;
342 break;
343 case 'q':
344 showprogress = 0;
345 break;
346 case '?': 305 case '?':
347 default: 306 default:
348 usage(); 307 usage();
@@ -1287,3 +1246,25 @@ getttywidth(void)
1287 else 1246 else
1288 return (80); 1247 return (80);
1289} 1248}
1249
1250void
1251addargs(char *fmt, ...)
1252{
1253 va_list ap;
1254 char buf[1024];
1255
1256 va_start(ap, fmt);
1257 vsnprintf(buf, sizeof(buf), fmt, ap);
1258 va_end(ap);
1259
1260 if (args.list == NULL) {
1261 args.nalloc = 32;
1262 args.num = 0;
1263 args.list = xmalloc(args.nalloc * sizeof(char *));
1264 } else if (args.num+2 >= args.nalloc) {
1265 args.nalloc *= 2;
1266 args.list = xrealloc(args.list, args.nalloc * sizeof(char *));
1267 }
1268 args.list[args.num++] = xstrdup(buf);
1269 args.list[args.num] = NULL;
1270}