diff options
Diffstat (limited to 'scp.c')
-rw-r--r-- | scp.c | 63 |
1 files changed, 38 insertions, 25 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: scp.c,v 1.175 2013/06/04 19:12:23 dtucker Exp $ */ | 1 | /* $OpenBSD: scp.c,v 1.176 2013/06/17 04:48:42 guenther 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 | ||
553 | static int | ||
554 | do_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 | |||
553 | void | 571 | void |
554 | toremote(char *targ, int argc, char **argv) | 572 | toremote(char *targ, int argc, char **argv) |
555 | { | 573 | { |
@@ -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) |
@@ -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,29 @@ 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 || (time_t)ull != ull) | ||
980 | setimes = 0; /* out of range */ | ||
981 | mtime.tv_sec = ull; | ||
976 | mtime.tv_usec = strtol(cp, &cp, 10); | 982 | mtime.tv_usec = strtol(cp, &cp, 10); |
977 | if (!cp || *cp++ != ' ') | 983 | if (!cp || *cp++ != ' ' || mtime.tv_usec < 0 || |
984 | mtime.tv_usec > 999999) | ||
978 | SCREWUP("mtime.usec not delimited"); | 985 | SCREWUP("mtime.usec not delimited"); |
979 | atime.tv_sec = strtol(cp, &cp, 10); | 986 | if (!isdigit((unsigned char)*cp)) |
987 | SCREWUP("atime.sec not present"); | ||
988 | ull = strtoull(cp, &cp, 10); | ||
980 | if (!cp || *cp++ != ' ') | 989 | if (!cp || *cp++ != ' ') |
981 | SCREWUP("atime.sec not delimited"); | 990 | SCREWUP("atime.sec not delimited"); |
991 | if ((time_t)ull < 0 || (time_t)ull != ull) | ||
992 | setimes = 0; /* out of range */ | ||
993 | atime.tv_sec = ull; | ||
982 | atime.tv_usec = strtol(cp, &cp, 10); | 994 | atime.tv_usec = strtol(cp, &cp, 10); |
983 | if (!cp || *cp++ != '\0') | 995 | if (!cp || *cp++ != '\0' || atime.tv_usec < 0 || |
996 | atime.tv_usec > 999999) | ||
984 | SCREWUP("atime.usec not delimited"); | 997 | SCREWUP("atime.usec not delimited"); |
985 | (void) atomicio(vwrite, remout, "", 1); | 998 | (void) atomicio(vwrite, remout, "", 1); |
986 | continue; | 999 | continue; |