summaryrefslogtreecommitdiff
path: root/scp.c
diff options
context:
space:
mode:
Diffstat (limited to 'scp.c')
-rw-r--r--scp.c108
1 files changed, 62 insertions, 46 deletions
diff --git a/scp.c b/scp.c
index 4f9247c2d..35d4c5f71 100644
--- a/scp.c
+++ b/scp.c
@@ -52,7 +52,11 @@
52 * 2. Redistributions in binary form must reproduce the above copyright 52 * 2. Redistributions in binary form must reproduce the above copyright
53 * notice, this list of conditions and the following disclaimer in the 53 * notice, this list of conditions and the following disclaimer in the
54 * documentation and/or other materials provided with the distribution. 54 * documentation and/or other materials provided with the distribution.
55 * 3. Neither the name of the University nor the names of its contributors 55 * 3. All advertising materials mentioning features or use of this software
56 * must display the following acknowledgement:
57 * This product includes software developed by the University of
58 * California, Berkeley and its contributors.
59 * 4. Neither the name of the University nor the names of its contributors
56 * may be used to endorse or promote products derived from this software 60 * may be used to endorse or promote products derived from this software
57 * without specific prior written permission. 61 * without specific prior written permission.
58 * 62 *
@@ -71,7 +75,7 @@
71 */ 75 */
72 76
73#include "includes.h" 77#include "includes.h"
74RCSID("$OpenBSD: scp.c,v 1.108 2003/07/18 01:54:25 deraadt Exp $"); 78RCSID("$OpenBSD: scp.c,v 1.102 2003/03/05 22:33:43 markus Exp $");
75 79
76#include "xmalloc.h" 80#include "xmalloc.h"
77#include "atomicio.h" 81#include "atomicio.h"
@@ -107,16 +111,7 @@ int showprogress = 1;
107char *ssh_program = _PATH_SSH_PROGRAM; 111char *ssh_program = _PATH_SSH_PROGRAM;
108 112
109/* This is used to store the pid of ssh_program */ 113/* This is used to store the pid of ssh_program */
110pid_t do_cmd_pid = -1; 114pid_t do_cmd_pid;
111
112static void
113killchild(int signo)
114{
115 if (do_cmd_pid > 1)
116 kill(do_cmd_pid, signo);
117
118 _exit(1);
119}
120 115
121/* 116/*
122 * This function executes the given command as the specified user on the 117 * This function executes the given command as the specified user on the
@@ -151,7 +146,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
151 close(reserved[0]); 146 close(reserved[0]);
152 close(reserved[1]); 147 close(reserved[1]);
153 148
154 /* Fork a child to execute the command on the remote host using ssh. */ 149 /* For a child to execute the command on the remote host using ssh. */
155 do_cmd_pid = fork(); 150 do_cmd_pid = fork();
156 if (do_cmd_pid == 0) { 151 if (do_cmd_pid == 0) {
157 /* Child. */ 152 /* Child. */
@@ -179,9 +174,6 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
179 *fdout = pin[1]; 174 *fdout = pin[1];
180 close(pout[1]); 175 close(pout[1]);
181 *fdin = pout[0]; 176 *fdin = pout[0];
182 signal(SIGTERM, killchild);
183 signal(SIGINT, killchild);
184 signal(SIGHUP, killchild);
185 return 0; 177 return 0;
186} 178}
187 179
@@ -214,7 +206,9 @@ void toremote(char *, int, char *[]);
214void usage(void); 206void usage(void);
215 207
216int 208int
217main(int argc, char **argv) 209main(argc, argv)
210 int argc;
211 char *argv[];
218{ 212{
219 int ch, fflag, tflag, status; 213 int ch, fflag, tflag, status;
220 double speed; 214 double speed;
@@ -222,7 +216,7 @@ main(int argc, char **argv)
222 extern char *optarg; 216 extern char *optarg;
223 extern int optind; 217 extern int optind;
224 218
225 __progname = ssh_get_progname(argv[0]); 219 __progname = get_progname(argv[0]);
226 220
227 args.list = NULL; 221 args.list = NULL;
228 addargs(&args, "ssh"); /* overwritten with ssh_program */ 222 addargs(&args, "ssh"); /* overwritten with ssh_program */
@@ -298,7 +292,7 @@ main(int argc, char **argv)
298 argv += optind; 292 argv += optind;
299 293
300 if ((pwd = getpwuid(userid = getuid())) == NULL) 294 if ((pwd = getpwuid(userid = getuid())) == NULL)
301 fatal("unknown user %u", (u_int) userid); 295 fatal("unknown user %d", (int) userid);
302 296
303 if (!isatty(STDERR_FILENO)) 297 if (!isatty(STDERR_FILENO))
304 showprogress = 0; 298 showprogress = 0;
@@ -359,7 +353,9 @@ main(int argc, char **argv)
359} 353}
360 354
361void 355void
362toremote(char *targ, int argc, char **argv) 356toremote(targ, argc, argv)
357 char *targ, *argv[];
358 int argc;
363{ 359{
364 int i, len; 360 int i, len;
365 char *bp, *host, *src, *suser, *thost, *tuser; 361 char *bp, *host, *src, *suser, *thost, *tuser;
@@ -447,7 +443,9 @@ toremote(char *targ, int argc, char **argv)
447} 443}
448 444
449void 445void
450tolocal(int argc, char **argv) 446tolocal(argc, argv)
447 int argc;
448 char *argv[];
451{ 449{
452 int i, len; 450 int i, len;
453 char *bp, *host, *src, *suser; 451 char *bp, *host, *src, *suser;
@@ -496,7 +494,9 @@ tolocal(int argc, char **argv)
496} 494}
497 495
498void 496void
499source(int argc, char **argv) 497source(argc, argv)
498 int argc;
499 char *argv[];
500{ 500{
501 struct stat stb; 501 struct stat stb;
502 static BUF buffer; 502 static BUF buffer;
@@ -549,18 +549,25 @@ syserr: run_err("%s: %s", name, strerror(errno));
549 (void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n", 549 (void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n",
550 (u_long) stb.st_mtime, 550 (u_long) stb.st_mtime,
551 (u_long) stb.st_atime); 551 (u_long) stb.st_atime);
552 (void) atomicio(vwrite, remout, buf, strlen(buf)); 552 (void) atomicio(write, remout, buf, strlen(buf));
553 if (response() < 0) 553 if (response() < 0)
554 goto next; 554 goto next;
555 } 555 }
556#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) 556#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
557#ifdef HAVE_LONG_LONG_INT
557 snprintf(buf, sizeof buf, "C%04o %lld %s\n", 558 snprintf(buf, sizeof buf, "C%04o %lld %s\n",
558 (u_int) (stb.st_mode & FILEMODEMASK), 559 (u_int) (stb.st_mode & FILEMODEMASK),
559 (int64_t)stb.st_size, last); 560 (long long)stb.st_size, last);
561#else
562 /* XXX: Handle integer overflow? */
563 snprintf(buf, sizeof buf, "C%04o %lu %s\n",
564 (u_int) (stb.st_mode & FILEMODEMASK),
565 (u_long) stb.st_size, last);
566#endif
560 if (verbose_mode) { 567 if (verbose_mode) {
561 fprintf(stderr, "Sending file modes: %s", buf); 568 fprintf(stderr, "Sending file modes: %s", buf);
562 } 569 }
563 (void) atomicio(vwrite, remout, buf, strlen(buf)); 570 (void) atomicio(write, remout, buf, strlen(buf));
564 if (response() < 0) 571 if (response() < 0)
565 goto next; 572 goto next;
566 if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) { 573 if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) {
@@ -580,9 +587,9 @@ next: (void) close(fd);
580 haderr = result >= 0 ? EIO : errno; 587 haderr = result >= 0 ? EIO : errno;
581 } 588 }
582 if (haderr) 589 if (haderr)
583 (void) atomicio(vwrite, remout, bp->buf, amt); 590 (void) atomicio(write, remout, bp->buf, amt);
584 else { 591 else {
585 result = atomicio(vwrite, remout, bp->buf, amt); 592 result = atomicio(write, remout, bp->buf, amt);
586 if (result != amt) 593 if (result != amt)
587 haderr = result >= 0 ? EIO : errno; 594 haderr = result >= 0 ? EIO : errno;
588 statbytes += result; 595 statbytes += result;
@@ -596,7 +603,7 @@ next: (void) close(fd);
596 if (close(fd) < 0 && !haderr) 603 if (close(fd) < 0 && !haderr)
597 haderr = errno; 604 haderr = errno;
598 if (!haderr) 605 if (!haderr)
599 (void) atomicio(vwrite, remout, "", 1); 606 (void) atomicio(write, remout, "", 1);
600 else 607 else
601 run_err("%s: %s", name, strerror(haderr)); 608 run_err("%s: %s", name, strerror(haderr));
602 (void) response(); 609 (void) response();
@@ -604,7 +611,9 @@ next: (void) close(fd);
604} 611}
605 612
606void 613void
607rsource(char *name, struct stat *statp) 614rsource(name, statp)
615 char *name;
616 struct stat *statp;
608{ 617{
609 DIR *dirp; 618 DIR *dirp;
610 struct dirent *dp; 619 struct dirent *dp;
@@ -623,7 +632,7 @@ rsource(char *name, struct stat *statp)
623 (void) snprintf(path, sizeof(path), "T%lu 0 %lu 0\n", 632 (void) snprintf(path, sizeof(path), "T%lu 0 %lu 0\n",
624 (u_long) statp->st_mtime, 633 (u_long) statp->st_mtime,
625 (u_long) statp->st_atime); 634 (u_long) statp->st_atime);
626 (void) atomicio(vwrite, remout, path, strlen(path)); 635 (void) atomicio(write, remout, path, strlen(path));
627 if (response() < 0) { 636 if (response() < 0) {
628 closedir(dirp); 637 closedir(dirp);
629 return; 638 return;
@@ -633,7 +642,7 @@ rsource(char *name, struct stat *statp)
633 (u_int) (statp->st_mode & FILEMODEMASK), 0, last); 642 (u_int) (statp->st_mode & FILEMODEMASK), 0, last);
634 if (verbose_mode) 643 if (verbose_mode)
635 fprintf(stderr, "Entering directory: %s", path); 644 fprintf(stderr, "Entering directory: %s", path);
636 (void) atomicio(vwrite, remout, path, strlen(path)); 645 (void) atomicio(write, remout, path, strlen(path));
637 if (response() < 0) { 646 if (response() < 0) {
638 closedir(dirp); 647 closedir(dirp);
639 return; 648 return;
@@ -652,7 +661,7 @@ rsource(char *name, struct stat *statp)
652 source(1, vect); 661 source(1, vect);
653 } 662 }
654 (void) closedir(dirp); 663 (void) closedir(dirp);
655 (void) atomicio(vwrite, remout, "E\n", 2); 664 (void) atomicio(write, remout, "E\n", 2);
656 (void) response(); 665 (void) response();
657} 666}
658 667
@@ -711,7 +720,9 @@ bwlimit(int amount)
711} 720}
712 721
713void 722void
714sink(int argc, char **argv) 723sink(argc, argv)
724 int argc;
725 char *argv[];
715{ 726{
716 static BUF buffer; 727 static BUF buffer;
717 struct stat stb; 728 struct stat stb;
@@ -742,7 +753,7 @@ sink(int argc, char **argv)
742 if (targetshouldbedirectory) 753 if (targetshouldbedirectory)
743 verifydir(targ); 754 verifydir(targ);
744 755
745 (void) atomicio(vwrite, remout, "", 1); 756 (void) atomicio(write, remout, "", 1);
746 if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) 757 if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode))
747 targisdir = 1; 758 targisdir = 1;
748 for (first = 1;; first = 0) { 759 for (first = 1;; first = 0) {
@@ -760,7 +771,7 @@ sink(int argc, char **argv)
760 771
761 if (buf[0] == '\01' || buf[0] == '\02') { 772 if (buf[0] == '\01' || buf[0] == '\02') {
762 if (iamremote == 0) 773 if (iamremote == 0)
763 (void) atomicio(vwrite, STDERR_FILENO, 774 (void) atomicio(write, STDERR_FILENO,
764 buf + 1, strlen(buf + 1)); 775 buf + 1, strlen(buf + 1));
765 if (buf[0] == '\02') 776 if (buf[0] == '\02')
766 exit(1); 777 exit(1);
@@ -768,7 +779,7 @@ sink(int argc, char **argv)
768 continue; 779 continue;
769 } 780 }
770 if (buf[0] == 'E') { 781 if (buf[0] == 'E') {
771 (void) atomicio(vwrite, remout, "", 1); 782 (void) atomicio(write, remout, "", 1);
772 return; 783 return;
773 } 784 }
774 if (ch == '\n') 785 if (ch == '\n')
@@ -790,7 +801,7 @@ sink(int argc, char **argv)
790 atime.tv_usec = strtol(cp, &cp, 10); 801 atime.tv_usec = strtol(cp, &cp, 10);
791 if (!cp || *cp++ != '\0') 802 if (!cp || *cp++ != '\0')
792 SCREWUP("atime.usec not delimited"); 803 SCREWUP("atime.usec not delimited");
793 (void) atomicio(vwrite, remout, "", 1); 804 (void) atomicio(write, remout, "", 1);
794 continue; 805 continue;
795 } 806 }
796 if (*cp != 'C' && *cp != 'D') { 807 if (*cp != 'C' && *cp != 'D') {
@@ -875,7 +886,7 @@ sink(int argc, char **argv)
875bad: run_err("%s: %s", np, strerror(errno)); 886bad: run_err("%s: %s", np, strerror(errno));
876 continue; 887 continue;
877 } 888 }
878 (void) atomicio(vwrite, remout, "", 1); 889 (void) atomicio(write, remout, "", 1);
879 if ((bp = allocbuf(&buffer, ofd, 4096)) == NULL) { 890 if ((bp = allocbuf(&buffer, ofd, 4096)) == NULL) {
880 (void) close(ofd); 891 (void) close(ofd);
881 continue; 892 continue;
@@ -912,7 +923,7 @@ bad: run_err("%s: %s", np, strerror(errno));
912 if (count == bp->cnt) { 923 if (count == bp->cnt) {
913 /* Keep reading so we stay sync'd up. */ 924 /* Keep reading so we stay sync'd up. */
914 if (wrerr == NO) { 925 if (wrerr == NO) {
915 j = atomicio(vwrite, ofd, bp->buf, count); 926 j = atomicio(write, ofd, bp->buf, count);
916 if (j != count) { 927 if (j != count) {
917 wrerr = YES; 928 wrerr = YES;
918 wrerrno = j >= 0 ? EIO : errno; 929 wrerrno = j >= 0 ? EIO : errno;
@@ -925,7 +936,7 @@ bad: run_err("%s: %s", np, strerror(errno));
925 if (showprogress) 936 if (showprogress)
926 stop_progress_meter(); 937 stop_progress_meter();
927 if (count != 0 && wrerr == NO && 938 if (count != 0 && wrerr == NO &&
928 (j = atomicio(vwrite, ofd, bp->buf, count)) != count) { 939 (j = atomicio(write, ofd, bp->buf, count)) != count) {
929 wrerr = YES; 940 wrerr = YES;
930 wrerrno = j >= 0 ? EIO : errno; 941 wrerrno = j >= 0 ? EIO : errno;
931 } 942 }
@@ -970,7 +981,7 @@ bad: run_err("%s: %s", np, strerror(errno));
970 run_err("%s: %s", np, strerror(wrerrno)); 981 run_err("%s: %s", np, strerror(wrerrno));
971 break; 982 break;
972 case NO: 983 case NO:
973 (void) atomicio(vwrite, remout, "", 1); 984 (void) atomicio(write, remout, "", 1);
974 break; 985 break;
975 case DISPLAYED: 986 case DISPLAYED:
976 break; 987 break;
@@ -1005,7 +1016,7 @@ response(void)
1005 } while (cp < &rbuf[sizeof(rbuf) - 1] && ch != '\n'); 1016 } while (cp < &rbuf[sizeof(rbuf) - 1] && ch != '\n');
1006 1017
1007 if (!iamremote) 1018 if (!iamremote)
1008 (void) atomicio(vwrite, STDERR_FILENO, rbuf, cp - rbuf); 1019 (void) atomicio(write, STDERR_FILENO, rbuf, cp - rbuf);
1009 ++errs; 1020 ++errs;
1010 if (resp == 1) 1021 if (resp == 1)
1011 return (-1); 1022 return (-1);
@@ -1050,7 +1061,8 @@ run_err(const char *fmt,...)
1050} 1061}
1051 1062
1052void 1063void
1053verifydir(char *cp) 1064verifydir(cp)
1065 char *cp;
1054{ 1066{
1055 struct stat stb; 1067 struct stat stb;
1056 1068
@@ -1064,7 +1076,8 @@ verifydir(char *cp)
1064} 1076}
1065 1077
1066int 1078int
1067okname(char *cp0) 1079okname(cp0)
1080 char *cp0;
1068{ 1081{
1069 int c; 1082 int c;
1070 char *cp; 1083 char *cp;
@@ -1094,7 +1107,9 @@ bad: fprintf(stderr, "%s: invalid user name\n", cp0);
1094} 1107}
1095 1108
1096BUF * 1109BUF *
1097allocbuf(BUF *bp, int fd, int blksize) 1110allocbuf(bp, fd, blksize)
1111 BUF *bp;
1112 int fd, blksize;
1098{ 1113{
1099 size_t size; 1114 size_t size;
1100#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE 1115#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
@@ -1122,7 +1137,8 @@ allocbuf(BUF *bp, int fd, int blksize)
1122} 1137}
1123 1138
1124void 1139void
1125lostconn(int signo) 1140lostconn(signo)
1141 int signo;
1126{ 1142{
1127 if (!iamremote) 1143 if (!iamremote)
1128 write(STDERR_FILENO, "lost connection\n", 16); 1144 write(STDERR_FILENO, "lost connection\n", 16);