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