summaryrefslogtreecommitdiff
path: root/scp.c
diff options
context:
space:
mode:
Diffstat (limited to 'scp.c')
-rw-r--r--scp.c137
1 files changed, 53 insertions, 84 deletions
diff --git a/scp.c b/scp.c
index 02feba9c1..d2e4224bb 100644
--- a/scp.c
+++ b/scp.c
@@ -11,6 +11,8 @@
11*/ 11*/
12 12
13/* 13/*
14 * Parts from:
15 *
14 * Copyright (c) 1983, 1990, 1992, 1993, 1995 16 * Copyright (c) 1983, 1990, 1992, 1993, 1995
15 * The Regents of the University of California. All rights reserved. 17 * The Regents of the University of California. All rights reserved.
16 * 18 *
@@ -45,7 +47,7 @@
45 */ 47 */
46 48
47#include "includes.h" 49#include "includes.h"
48RCSID("$OpenBSD: scp.c,v 1.33 2000/07/13 23:19:31 provos Exp $"); 50RCSID("$OpenBSD: scp.c,v 1.35 2000/08/19 02:50:07 deraadt Exp $");
49 51
50#include "ssh.h" 52#include "ssh.h"
51#include "xmalloc.h" 53#include "xmalloc.h"
@@ -69,6 +71,7 @@ void progressmeter(int);
69 71
70/* Returns width of the terminal (for progress meter calculations). */ 72/* Returns width of the terminal (for progress meter calculations). */
71int getttywidth(void); 73int getttywidth(void);
74int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc);
72 75
73/* Time a transfer started. */ 76/* Time a transfer started. */
74static struct timeval start; 77static struct timeval start;
@@ -111,6 +114,9 @@ char *identity = NULL;
111/* This is the port to use in contacting the remote site (is non-NULL). */ 114/* This is the port to use in contacting the remote site (is non-NULL). */
112char *port = NULL; 115char *port = NULL;
113 116
117/* This is the program to execute for the secured connection. ("ssh" or -S) */
118char *ssh_program = SSH_PROGRAM;
119
114/* 120/*
115 * This function executes the given command as the specified user on the 121 * This function executes the given command as the specified user on the
116 * given host. This returns < 0 if execution fails, and >= 0 otherwise. This 122 * given host. This returns < 0 if execution fails, and >= 0 otherwise. This
@@ -118,13 +124,13 @@ char *port = NULL;
118 */ 124 */
119 125
120int 126int
121do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout) 127do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
122{ 128{
123 int pin[2], pout[2], reserved[2]; 129 int pin[2], pout[2], reserved[2];
124 130
125 if (verbose_mode) 131 if (verbose_mode)
126 fprintf(stderr, "Executing: host %s, user %s, command %s\n", 132 fprintf(stderr, "Executing: host %s, user %s, command %s\n",
127 host, remuser ? remuser : "(unspecified)", cmd); 133 host, remuser ? remuser : "(unspecified)", cmd);
128 134
129 /* 135 /*
130 * Reserve two descriptors so that the real pipes won't get 136 * Reserve two descriptors so that the real pipes won't get
@@ -144,7 +150,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
144 150
145 /* For a child to execute the command on the remote host using ssh. */ 151 /* For a child to execute the command on the remote host using ssh. */
146 if (fork() == 0) { 152 if (fork() == 0) {
147 char *args[100]; 153 char *args[100]; /* XXX careful */
148 unsigned int i; 154 unsigned int i;
149 155
150 /* Child. */ 156 /* Child. */
@@ -156,7 +162,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
156 close(pout[1]); 162 close(pout[1]);
157 163
158 i = 0; 164 i = 0;
159 args[i++] = SSH_PROGRAM; 165 args[i++] = ssh_program;
160 args[i++] = "-x"; 166 args[i++] = "-x";
161 args[i++] = "-oFallBackToRsh no"; 167 args[i++] = "-oFallBackToRsh no";
162 if (IPv4) 168 if (IPv4)
@@ -189,8 +195,8 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
189 args[i++] = cmd; 195 args[i++] = cmd;
190 args[i++] = NULL; 196 args[i++] = NULL;
191 197
192 execvp(SSH_PROGRAM, args); 198 execvp(ssh_program, args);
193 perror(SSH_PROGRAM); 199 perror(ssh_program);
194 exit(1); 200 exit(1);
195 } 201 }
196 /* Parent. Close the other side, and return the local side. */ 202 /* Parent. Close the other side, and return the local side. */
@@ -214,8 +220,6 @@ fatal(const char *fmt,...)
214 exit(255); 220 exit(255);
215} 221}
216 222
217/* This stuff used to be in BSD rcp extern.h. */
218
219typedef struct { 223typedef struct {
220 int cnt; 224 int cnt;
221 char *buf; 225 char *buf;
@@ -231,8 +235,6 @@ int okname(char *);
231void run_err(const char *,...); 235void run_err(const char *,...);
232void verifydir(char *); 236void verifydir(char *);
233 237
234/* Stuff from BSD rcp.c continues. */
235
236struct passwd *pwd; 238struct passwd *pwd;
237uid_t userid; 239uid_t userid;
238int errs, remin, remout; 240int errs, remin, remout;
@@ -260,7 +262,7 @@ main(argc, argv)
260 extern int optind; 262 extern int optind;
261 263
262 fflag = tflag = 0; 264 fflag = tflag = 0;
263 while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46")) != EOF) 265 while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S")) != EOF)
264 switch (ch) { 266 switch (ch) {
265 /* User-visible flags. */ 267 /* User-visible flags. */
266 case '4': 268 case '4':
@@ -278,6 +280,10 @@ main(argc, argv)
278 case 'r': 280 case 'r':
279 iamrecursive = 1; 281 iamrecursive = 1;
280 break; 282 break;
283 case 'S':
284 ssh_program = optarg;
285 break;
286
281 /* Server options. */ 287 /* Server options. */
282 case 'd': 288 case 'd':
283 targetshouldbedirectory = 1; 289 targetshouldbedirectory = 1;
@@ -343,8 +349,8 @@ main(argc, argv)
343 remin = remout = -1; 349 remin = remout = -1;
344 /* Command to be executed on remote system using "ssh". */ 350 /* Command to be executed on remote system using "ssh". */
345 (void) sprintf(cmd, "scp%s%s%s%s", verbose_mode ? " -v" : "", 351 (void) sprintf(cmd, "scp%s%s%s%s", verbose_mode ? " -v" : "",
346 iamrecursive ? " -r" : "", pflag ? " -p" : "", 352 iamrecursive ? " -r" : "", pflag ? " -p" : "",
347 targetshouldbedirectory ? " -d" : ""); 353 targetshouldbedirectory ? " -d" : "");
348 354
349 (void) signal(SIGPIPE, lostconn); 355 (void) signal(SIGPIPE, lostconn);
350 356
@@ -401,9 +407,9 @@ toremote(targ, argc, argv)
401 if (*src == 0) 407 if (*src == 0)
402 src = "."; 408 src = ".";
403 host = strchr(argv[i], '@'); 409 host = strchr(argv[i], '@');
404 len = strlen(SSH_PROGRAM) + strlen(argv[i]) + 410 len = strlen(ssh_program) + strlen(argv[i]) +
405 strlen(src) + (tuser ? strlen(tuser) : 0) + 411 strlen(src) + (tuser ? strlen(tuser) : 0) +
406 strlen(thost) + strlen(targ) + CMDNEEDS + 32; 412 strlen(thost) + strlen(targ) + CMDNEEDS + 32;
407 bp = xmalloc(len); 413 bp = xmalloc(len);
408 if (host) { 414 if (host) {
409 *host++ = 0; 415 *host++ = 0;
@@ -414,19 +420,19 @@ toremote(targ, argc, argv)
414 else if (!okname(suser)) 420 else if (!okname(suser))
415 continue; 421 continue;
416 (void) sprintf(bp, 422 (void) sprintf(bp,
417 "%s%s -x -o'FallBackToRsh no' -n -l %s %s %s %s '%s%s%s:%s'", 423 "%s%s -x -o'FallBackToRsh no' -n -l %s %s %s %s '%s%s%s:%s'",
418 SSH_PROGRAM, verbose_mode ? " -v" : "", 424 ssh_program, verbose_mode ? " -v" : "",
419 suser, host, cmd, src, 425 suser, host, cmd, src,
420 tuser ? tuser : "", tuser ? "@" : "", 426 tuser ? tuser : "", tuser ? "@" : "",
421 thost, targ); 427 thost, targ);
422 } else { 428 } else {
423 host = cleanhostname(argv[i]); 429 host = cleanhostname(argv[i]);
424 (void) sprintf(bp, 430 (void) sprintf(bp,
425 "exec %s%s -x -o'FallBackToRsh no' -n %s %s %s '%s%s%s:%s'", 431 "exec %s%s -x -o'FallBackToRsh no' -n %s %s %s '%s%s%s:%s'",
426 SSH_PROGRAM, verbose_mode ? " -v" : "", 432 ssh_program, verbose_mode ? " -v" : "",
427 host, cmd, src, 433 host, cmd, src,
428 tuser ? tuser : "", tuser ? "@" : "", 434 tuser ? tuser : "", tuser ? "@" : "",
429 thost, targ); 435 thost, targ);
430 } 436 }
431 if (verbose_mode) 437 if (verbose_mode)
432 fprintf(stderr, "Executing: %s\n", bp); 438 fprintf(stderr, "Executing: %s\n", bp);
@@ -438,8 +444,8 @@ toremote(targ, argc, argv)
438 bp = xmalloc(len); 444 bp = xmalloc(len);
439 (void) sprintf(bp, "%s -t %s", cmd, targ); 445 (void) sprintf(bp, "%s -t %s", cmd, targ);
440 host = cleanhostname(thost); 446 host = cleanhostname(thost);
441 if (do_cmd(host, tuser, 447 if (do_cmd(host, tuser, bp, &remin,
442 bp, &remin, &remout) < 0) 448 &remout, argc) < 0)
443 exit(1); 449 exit(1);
444 if (response() < 0) 450 if (response() < 0)
445 exit(1); 451 exit(1);
@@ -461,11 +467,11 @@ tolocal(argc, argv)
461 for (i = 0; i < argc - 1; i++) { 467 for (i = 0; i < argc - 1; i++) {
462 if (!(src = colon(argv[i]))) { /* Local to local. */ 468 if (!(src = colon(argv[i]))) { /* Local to local. */
463 len = strlen(_PATH_CP) + strlen(argv[i]) + 469 len = strlen(_PATH_CP) + strlen(argv[i]) +
464 strlen(argv[argc - 1]) + 20; 470 strlen(argv[argc - 1]) + 20;
465 bp = xmalloc(len); 471 bp = xmalloc(len);
466 (void) sprintf(bp, "exec %s%s%s %s %s", _PATH_CP, 472 (void) sprintf(bp, "exec %s%s%s %s %s", _PATH_CP,
467 iamrecursive ? " -r" : "", pflag ? " -p" : "", 473 iamrecursive ? " -r" : "", pflag ? " -p" : "",
468 argv[i], argv[argc - 1]); 474 argv[i], argv[argc - 1]);
469 if (verbose_mode) 475 if (verbose_mode)
470 fprintf(stderr, "Executing: %s\n", bp); 476 fprintf(stderr, "Executing: %s\n", bp);
471 if (system(bp)) 477 if (system(bp))
@@ -491,7 +497,7 @@ tolocal(argc, argv)
491 len = strlen(src) + CMDNEEDS + 20; 497 len = strlen(src) + CMDNEEDS + 20;
492 bp = xmalloc(len); 498 bp = xmalloc(len);
493 (void) sprintf(bp, "%s -f %s", cmd, src); 499 (void) sprintf(bp, "%s -f %s", cmd, src);
494 if (do_cmd(host, suser, bp, &remin, &remout) < 0) { 500 if (do_cmd(host, suser, bp, &remin, &remout, argc) < 0) {
495 (void) xfree(bp); 501 (void) xfree(bp);
496 ++errs; 502 ++errs;
497 continue; 503 continue;
@@ -548,8 +554,8 @@ syserr: run_err("%s: %s", name, strerror(errno));
548 * versions expecting microseconds. 554 * versions expecting microseconds.
549 */ 555 */
550 (void) sprintf(buf, "T%lu 0 %lu 0\n", 556 (void) sprintf(buf, "T%lu 0 %lu 0\n",
551 (unsigned long) stb.st_mtime, 557 (unsigned long) stb.st_mtime,
552 (unsigned long) stb.st_atime); 558 (unsigned long) stb.st_atime);
553 (void) atomicio(write, remout, buf, strlen(buf)); 559 (void) atomicio(write, remout, buf, strlen(buf));
554 if (response() < 0) 560 if (response() < 0)
555 goto next; 561 goto next;
@@ -626,8 +632,8 @@ rsource(name, statp)
626 last++; 632 last++;
627 if (pflag) { 633 if (pflag) {
628 (void) sprintf(path, "T%lu 0 %lu 0\n", 634 (void) sprintf(path, "T%lu 0 %lu 0\n",
629 (unsigned long) statp->st_mtime, 635 (unsigned long) statp->st_mtime,
630 (unsigned long) statp->st_atime); 636 (unsigned long) statp->st_atime);
631 (void) atomicio(write, remout, path, strlen(path)); 637 (void) atomicio(write, remout, path, strlen(path));
632 if (response() < 0) { 638 if (response() < 0) {
633 closedir(dirp); 639 closedir(dirp);
@@ -635,8 +641,7 @@ rsource(name, statp)
635 } 641 }
636 } 642 }
637 (void) sprintf(path, "D%04o %d %.1024s\n", 643 (void) sprintf(path, "D%04o %d %.1024s\n",
638 (unsigned int) (statp->st_mode & FILEMODEMASK), 644 (unsigned int) (statp->st_mode & FILEMODEMASK), 0, last);
639 0, last);
640 if (verbose_mode) 645 if (verbose_mode)
641 fprintf(stderr, "Entering directory: %s", path); 646 fprintf(stderr, "Entering directory: %s", path);
642 (void) atomicio(write, remout, path, strlen(path)); 647 (void) atomicio(write, remout, path, strlen(path));
@@ -783,7 +788,7 @@ sink(argc, argv)
783 if (need > cursize) 788 if (need > cursize)
784 namebuf = xmalloc(need); 789 namebuf = xmalloc(need);
785 (void) sprintf(namebuf, "%s%s%s", targ, 790 (void) sprintf(namebuf, "%s%s%s", targ,
786 *targ ? "/" : "", cp); 791 *targ ? "/" : "", cp);
787 np = namebuf; 792 np = namebuf;
788 } else 793 } else
789 np = targ; 794 np = targ;
@@ -954,8 +959,9 @@ response()
954void 959void
955usage() 960usage()
956{ 961{
957 (void) fprintf(stderr, 962 (void) fprintf(stderr, "usage: scp "
958 "usage: scp [-pqrvC46] [-P port] [-c cipher] [-i identity] f1 f2; or:\n scp [options] f1 ... fn directory\n"); 963 "[-pqrvC46] [-S ssh] [-P port] [-c cipher] [-i identity] f1 f2; or:\n"
964 " scp [options] f1 ... fn directory\n");
959 exit(1); 965 exit(1);
960} 966}
961 967
@@ -984,43 +990,6 @@ run_err(const char *fmt,...)
984 } 990 }
985} 991}
986 992
987/* Stuff below is from BSD rcp util.c. */
988
989/*-
990 * Copyright (c) 1992, 1993
991 * The Regents of the University of California. All rights reserved.
992 *
993 * Redistribution and use in source and binary forms, with or without
994 * modification, are permitted provided that the following conditions
995 * are met:
996 * 1. Redistributions of source code must retain the above copyright
997 * notice, this list of conditions and the following disclaimer.
998 * 2. Redistributions in binary form must reproduce the above copyright
999 * notice, this list of conditions and the following disclaimer in the
1000 * documentation and/or other materials provided with the distribution.
1001 * 3. All advertising materials mentioning features or use of this software
1002 * must display the following acknowledgement:
1003 * This product includes software developed by the University of
1004 * California, Berkeley and its contributors.
1005 * 4. Neither the name of the University nor the names of its contributors
1006 * may be used to endorse or promote products derived from this software
1007 * without specific prior written permission.
1008 *
1009 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1010 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1011 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1012 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1013 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1014 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1015 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1016 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1017 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1018 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1019 * SUCH DAMAGE.
1020 *
1021 * $OpenBSD: scp.c,v 1.33 2000/07/13 23:19:31 provos Exp $
1022 */
1023
1024char * 993char *
1025colon(cp) 994colon(cp)
1026 char *cp; 995 char *cp;
@@ -1097,7 +1066,7 @@ allocbuf(bp, fd, blksize)
1097 size = blksize; 1066 size = blksize;
1098 else 1067 else
1099 size = blksize + (stb.st_blksize - blksize % stb.st_blksize) % 1068 size = blksize + (stb.st_blksize - blksize % stb.st_blksize) %
1100 stb.st_blksize; 1069 stb.st_blksize;
1101 if (bp->cnt >= size) 1070 if (bp->cnt >= size)
1102 return (bp); 1071 return (bp);
1103 if (bp->buf == NULL) 1072 if (bp->buf == NULL)
@@ -1228,14 +1197,14 @@ progressmeter(int flag)
1228 i = remaining / 3600; 1197 i = remaining / 3600;
1229 if (i) 1198 if (i)
1230 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), 1199 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
1231 "%2d:", i); 1200 "%2d:", i);
1232 else 1201 else
1233 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), 1202 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
1234 " "); 1203 " ");
1235 i = remaining % 3600; 1204 i = remaining % 3600;
1236 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), 1205 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
1237 "%02d:%02d%s", i / 60, i % 60, 1206 "%02d:%02d%s", i / 60, i % 60,
1238 (flag != 1) ? " ETA" : " "); 1207 (flag != 1) ? " ETA" : " ");
1239 } 1208 }
1240 atomicio(write, fileno(stdout), buf, strlen(buf)); 1209 atomicio(write, fileno(stdout), buf, strlen(buf));
1241 1210