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