summaryrefslogtreecommitdiff
path: root/scp.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2013-09-14 15:43:03 +0100
committerColin Watson <cjwatson@debian.org>2013-09-14 15:43:03 +0100
commit8faf8c84430cf3c19705b1d9f8889d256e7fd1fd (patch)
treee6cb74192adb00fda5e4d1457547851d7e0d86af /scp.c
parent328b60656f29db6306994d7498dede386ec2d1c3 (diff)
parentc41345ad7ee5a22689e2c009595e85fa27b4b39a (diff)
merge 6.3p1
Diffstat (limited to 'scp.c')
-rw-r--r--scp.c91
1 files changed, 52 insertions, 39 deletions
diff --git a/scp.c b/scp.c
index 645d7403b..28ded5e9a 100644
--- a/scp.c
+++ b/scp.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: scp.c,v 1.171 2011/09/09 22:37:01 djm Exp $ */ 1/* $OpenBSD: scp.c,v 1.178 2013/06/22 06:31:57 djm Exp $ */
2/* 2/*
3 * scp - secure remote copy. This is basically patched BSD rcp which 3 * scp - secure remote copy. This is basically patched BSD rcp which
4 * uses ssh to do the data transfer (instead of using rcmd). 4 * uses ssh to do the data transfer (instead of using rcmd).
@@ -550,6 +550,24 @@ scpio(void *_cnt, size_t s)
550 return 0; 550 return 0;
551} 551}
552 552
553static int
554do_times(int fd, int verb, const struct stat *sb)
555{
556 /* strlen(2^64) == 20; strlen(10^6) == 7 */
557 char buf[(20 + 7 + 2) * 2 + 2];
558
559 (void)snprintf(buf, sizeof(buf), "T%llu 0 %llu 0\n",
560 (unsigned long long) (sb->st_mtime < 0 ? 0 : sb->st_mtime),
561 (unsigned long long) (sb->st_atime < 0 ? 0 : sb->st_atime));
562 if (verb) {
563 fprintf(stderr, "File mtime %lld atime %lld\n",
564 (long long)sb->st_mtime, (long long)sb->st_atime);
565 fprintf(stderr, "Sending file timestamps: %s", buf);
566 }
567 (void) atomicio(vwrite, fd, buf, strlen(buf));
568 return (response());
569}
570
553void 571void
554toremote(char *targ, int argc, char **argv) 572toremote(char *targ, int argc, char **argv)
555{ 573{
@@ -578,7 +596,7 @@ toremote(char *targ, int argc, char **argv)
578 } 596 }
579 597
580 if (tuser != NULL && !okname(tuser)) { 598 if (tuser != NULL && !okname(tuser)) {
581 xfree(arg); 599 free(arg);
582 return; 600 return;
583 } 601 }
584 602
@@ -605,13 +623,13 @@ toremote(char *targ, int argc, char **argv)
605 *src == '-' ? "-- " : "", src); 623 *src == '-' ? "-- " : "", src);
606 if (do_cmd(host, suser, bp, &remin, &remout) < 0) 624 if (do_cmd(host, suser, bp, &remin, &remout) < 0)
607 exit(1); 625 exit(1);
608 (void) xfree(bp); 626 free(bp);
609 host = cleanhostname(thost); 627 host = cleanhostname(thost);
610 xasprintf(&bp, "%s -t %s%s", cmd, 628 xasprintf(&bp, "%s -t %s%s", cmd,
611 *targ == '-' ? "-- " : "", targ); 629 *targ == '-' ? "-- " : "", targ);
612 if (do_cmd2(host, tuser, bp, remin, remout) < 0) 630 if (do_cmd2(host, tuser, bp, remin, remout) < 0)
613 exit(1); 631 exit(1);
614 (void) xfree(bp); 632 free(bp);
615 (void) close(remin); 633 (void) close(remin);
616 (void) close(remout); 634 (void) close(remout);
617 remin = remout = -1; 635 remin = remout = -1;
@@ -662,12 +680,12 @@ toremote(char *targ, int argc, char **argv)
662 exit(1); 680 exit(1);
663 if (response() < 0) 681 if (response() < 0)
664 exit(1); 682 exit(1);
665 (void) xfree(bp); 683 free(bp);
666 } 684 }
667 source(1, argv + i); 685 source(1, argv + i);
668 } 686 }
669 } 687 }
670 xfree(arg); 688 free(arg);
671} 689}
672 690
673void 691void
@@ -711,11 +729,11 @@ tolocal(int argc, char **argv)
711 xasprintf(&bp, "%s -f %s%s", 729 xasprintf(&bp, "%s -f %s%s",
712 cmd, *src == '-' ? "-- " : "", src); 730 cmd, *src == '-' ? "-- " : "", src);
713 if (do_cmd(host, suser, bp, &remin, &remout) < 0) { 731 if (do_cmd(host, suser, bp, &remin, &remout) < 0) {
714 (void) xfree(bp); 732 free(bp);
715 ++errs; 733 ++errs;
716 continue; 734 continue;
717 } 735 }
718 xfree(bp); 736 free(bp);
719 sink(1, argv + argc - 1); 737 sink(1, argv + argc - 1);
720 (void) close(remin); 738 (void) close(remin);
721 remin = remout = -1; 739 remin = remout = -1;
@@ -774,21 +792,7 @@ syserr: run_err("%s: %s", name, strerror(errno));
774 ++last; 792 ++last;
775 curfile = last; 793 curfile = last;
776 if (pflag) { 794 if (pflag) {
777 /* 795 if (do_times(remout, verbose_mode, &stb) < 0)
778 * Make it compatible with possible future
779 * versions expecting microseconds.
780 */
781 (void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n",
782 (u_long) (stb.st_mtime < 0 ? 0 : stb.st_mtime),
783 (u_long) (stb.st_atime < 0 ? 0 : stb.st_atime));
784 if (verbose_mode) {
785 fprintf(stderr, "File mtime %ld atime %ld\n",
786 (long)stb.st_mtime, (long)stb.st_atime);
787 fprintf(stderr, "Sending file timestamps: %s",
788 buf);
789 }
790 (void) atomicio(vwrite, remout, buf, strlen(buf));
791 if (response() < 0)
792 goto next; 796 goto next;
793 } 797 }
794#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) 798#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
@@ -850,7 +854,7 @@ rsource(char *name, struct stat *statp)
850{ 854{
851 DIR *dirp; 855 DIR *dirp;
852 struct dirent *dp; 856 struct dirent *dp;
853 char *last, *vect[1], path[1100]; 857 char *last, *vect[1], path[MAXPATHLEN];
854 858
855 if (!(dirp = opendir(name))) { 859 if (!(dirp = opendir(name))) {
856 run_err("%s: %s", name, strerror(errno)); 860 run_err("%s: %s", name, strerror(errno));
@@ -862,11 +866,7 @@ rsource(char *name, struct stat *statp)
862 else 866 else
863 last++; 867 last++;
864 if (pflag) { 868 if (pflag) {
865 (void) snprintf(path, sizeof(path), "T%lu 0 %lu 0\n", 869 if (do_times(remout, verbose_mode, statp) < 0) {
866 (u_long) statp->st_mtime,
867 (u_long) statp->st_atime);
868 (void) atomicio(vwrite, remout, path, strlen(path));
869 if (response() < 0) {
870 closedir(dirp); 870 closedir(dirp);
871 return; 871 return;
872 } 872 }
@@ -912,6 +912,7 @@ sink(int argc, char **argv)
912 int amt, exists, first, ofd; 912 int amt, exists, first, ofd;
913 mode_t mode, omode, mask; 913 mode_t mode, omode, mask;
914 off_t size, statbytes; 914 off_t size, statbytes;
915 unsigned long long ull;
915 int setimes, targisdir, wrerrno = 0; 916 int setimes, targisdir, wrerrno = 0;
916 char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; 917 char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
917 struct timeval tv[2]; 918 struct timeval tv[2];
@@ -970,17 +971,31 @@ sink(int argc, char **argv)
970 if (*cp == 'T') { 971 if (*cp == 'T') {
971 setimes++; 972 setimes++;
972 cp++; 973 cp++;
973 mtime.tv_sec = strtol(cp, &cp, 10); 974 if (!isdigit((unsigned char)*cp))
975 SCREWUP("mtime.sec not present");
976 ull = strtoull(cp, &cp, 10);
974 if (!cp || *cp++ != ' ') 977 if (!cp || *cp++ != ' ')
975 SCREWUP("mtime.sec not delimited"); 978 SCREWUP("mtime.sec not delimited");
979 if ((time_t)ull < 0 ||
980 (unsigned long long)(time_t)ull != ull)
981 setimes = 0; /* out of range */
982 mtime.tv_sec = ull;
976 mtime.tv_usec = strtol(cp, &cp, 10); 983 mtime.tv_usec = strtol(cp, &cp, 10);
977 if (!cp || *cp++ != ' ') 984 if (!cp || *cp++ != ' ' || mtime.tv_usec < 0 ||
985 mtime.tv_usec > 999999)
978 SCREWUP("mtime.usec not delimited"); 986 SCREWUP("mtime.usec not delimited");
979 atime.tv_sec = strtol(cp, &cp, 10); 987 if (!isdigit((unsigned char)*cp))
988 SCREWUP("atime.sec not present");
989 ull = strtoull(cp, &cp, 10);
980 if (!cp || *cp++ != ' ') 990 if (!cp || *cp++ != ' ')
981 SCREWUP("atime.sec not delimited"); 991 SCREWUP("atime.sec not delimited");
992 if ((time_t)ull < 0 ||
993 (unsigned long long)(time_t)ull != ull)
994 setimes = 0; /* out of range */
995 atime.tv_sec = ull;
982 atime.tv_usec = strtol(cp, &cp, 10); 996 atime.tv_usec = strtol(cp, &cp, 10);
983 if (!cp || *cp++ != '\0') 997 if (!cp || *cp++ != '\0' || atime.tv_usec < 0 ||
998 atime.tv_usec > 999999)
984 SCREWUP("atime.usec not delimited"); 999 SCREWUP("atime.usec not delimited");
985 (void) atomicio(vwrite, remout, "", 1); 1000 (void) atomicio(vwrite, remout, "", 1);
986 continue; 1001 continue;
@@ -1023,8 +1038,7 @@ sink(int argc, char **argv)
1023 1038
1024 need = strlen(targ) + strlen(cp) + 250; 1039 need = strlen(targ) + strlen(cp) + 250;
1025 if (need > cursize) { 1040 if (need > cursize) {
1026 if (namebuf) 1041 free(namebuf);
1027 xfree(namebuf);
1028 namebuf = xmalloc(need); 1042 namebuf = xmalloc(need);
1029 cursize = need; 1043 cursize = need;
1030 } 1044 }
@@ -1063,12 +1077,11 @@ sink(int argc, char **argv)
1063 } 1077 }
1064 if (mod_flag) 1078 if (mod_flag)
1065 (void) chmod(vect[0], mode); 1079 (void) chmod(vect[0], mode);
1066 if (vect[0]) 1080 free(vect[0]);
1067 xfree(vect[0]);
1068 continue; 1081 continue;
1069 } 1082 }
1070 omode = mode; 1083 omode = mode;
1071 mode |= S_IWRITE; 1084 mode |= S_IWUSR;
1072 if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) { 1085 if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) {
1073bad: run_err("%s: %s", np, strerror(errno)); 1086bad: run_err("%s: %s", np, strerror(errno));
1074 continue; 1087 continue;
@@ -1325,7 +1338,7 @@ void
1325lostconn(int signo) 1338lostconn(int signo)
1326{ 1339{
1327 if (!iamremote) 1340 if (!iamremote)
1328 write(STDERR_FILENO, "lost connection\n", 16); 1341 (void)write(STDERR_FILENO, "lost connection\n", 16);
1329 if (signo) 1342 if (signo)
1330 _exit(1); 1343 _exit(1);
1331 else 1344 else