diff options
Diffstat (limited to 'scp.c')
-rw-r--r-- | scp.c | 108 |
1 files changed, 46 insertions, 62 deletions
@@ -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" |
78 | RCSID("$OpenBSD: scp.c,v 1.102 2003/03/05 22:33:43 markus Exp $"); | 74 | RCSID("$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; | |||
111 | char *ssh_program = _PATH_SSH_PROGRAM; | 107 | char *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 */ |
114 | pid_t do_cmd_pid; | 110 | pid_t do_cmd_pid = -1; |
111 | |||
112 | static void | ||
113 | killchild(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 *[]); | |||
206 | void usage(void); | 214 | void usage(void); |
207 | 215 | ||
208 | int | 216 | int |
209 | main(argc, argv) | 217 | main(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 | ||
355 | void | 361 | void |
356 | toremote(targ, argc, argv) | 362 | toremote(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 | ||
445 | void | 449 | void |
446 | tolocal(argc, argv) | 450 | tolocal(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 | ||
496 | void | 498 | void |
497 | source(argc, argv) | 499 | source(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 | ||
613 | void | 606 | void |
614 | rsource(name, statp) | 607 | rsource(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 | ||
722 | void | 713 | void |
723 | sink(argc, argv) | 714 | sink(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) | |||
886 | bad: run_err("%s: %s", np, strerror(errno)); | 875 | bad: 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 | ||
1063 | void | 1052 | void |
1064 | verifydir(cp) | 1053 | verifydir(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 | ||
1078 | int | 1066 | int |
1079 | okname(cp0) | 1067 | okname(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 | ||
1109 | BUF * | 1096 | BUF * |
1110 | allocbuf(bp, fd, blksize) | 1097 | allocbuf(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 | ||
1139 | void | 1124 | void |
1140 | lostconn(signo) | 1125 | lostconn(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); |