diff options
Diffstat (limited to 'crypto/openssh/scp.c')
-rw-r--r-- | crypto/openssh/scp.c | 108 |
1 files changed, 46 insertions, 62 deletions
diff --git a/crypto/openssh/scp.c b/crypto/openssh/scp.c index 35d4c5f..4f9247c 100644 --- a/crypto/openssh/scp.c +++ b/crypto/openssh/scp.c @@ -52,11 +52,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -75,7 +71,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: scp.c,v 1.102 2003/03/05 22:33:43 markus Exp $"); +RCSID("$OpenBSD: scp.c,v 1.108 2003/07/18 01:54:25 deraadt Exp $"); #include "xmalloc.h" #include "atomicio.h" @@ -111,7 +107,16 @@ int showprogress = 1; char *ssh_program = _PATH_SSH_PROGRAM; /* This is used to store the pid of ssh_program */ -pid_t do_cmd_pid; +pid_t do_cmd_pid = -1; + +static void +killchild(int signo) +{ + if (do_cmd_pid > 1) + kill(do_cmd_pid, signo); + + _exit(1); +} /* * 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) close(reserved[0]); close(reserved[1]); - /* For a child to execute the command on the remote host using ssh. */ + /* Fork a child to execute the command on the remote host using ssh. */ do_cmd_pid = fork(); if (do_cmd_pid == 0) { /* Child. */ @@ -174,6 +179,9 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc) *fdout = pin[1]; close(pout[1]); *fdin = pout[0]; + signal(SIGTERM, killchild); + signal(SIGINT, killchild); + signal(SIGHUP, killchild); return 0; } @@ -206,9 +214,7 @@ void toremote(char *, int, char *[]); void usage(void); int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char **argv) { int ch, fflag, tflag, status; double speed; @@ -216,7 +222,7 @@ main(argc, argv) extern char *optarg; extern int optind; - __progname = get_progname(argv[0]); + __progname = ssh_get_progname(argv[0]); args.list = NULL; addargs(&args, "ssh"); /* overwritten with ssh_program */ @@ -292,7 +298,7 @@ main(argc, argv) argv += optind; if ((pwd = getpwuid(userid = getuid())) == NULL) - fatal("unknown user %d", (int) userid); + fatal("unknown user %u", (u_int) userid); if (!isatty(STDERR_FILENO)) showprogress = 0; @@ -353,9 +359,7 @@ main(argc, argv) } void -toremote(targ, argc, argv) - char *targ, *argv[]; - int argc; +toremote(char *targ, int argc, char **argv) { int i, len; char *bp, *host, *src, *suser, *thost, *tuser; @@ -443,9 +447,7 @@ toremote(targ, argc, argv) } void -tolocal(argc, argv) - int argc; - char *argv[]; +tolocal(int argc, char **argv) { int i, len; char *bp, *host, *src, *suser; @@ -494,9 +496,7 @@ tolocal(argc, argv) } void -source(argc, argv) - int argc; - char *argv[]; +source(int argc, char **argv) { struct stat stb; static BUF buffer; @@ -549,25 +549,18 @@ syserr: run_err("%s: %s", name, strerror(errno)); (void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n", (u_long) stb.st_mtime, (u_long) stb.st_atime); - (void) atomicio(write, remout, buf, strlen(buf)); + (void) atomicio(vwrite, remout, buf, strlen(buf)); if (response() < 0) goto next; } #define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) -#ifdef HAVE_LONG_LONG_INT snprintf(buf, sizeof buf, "C%04o %lld %s\n", (u_int) (stb.st_mode & FILEMODEMASK), - (long long)stb.st_size, last); -#else - /* XXX: Handle integer overflow? */ - snprintf(buf, sizeof buf, "C%04o %lu %s\n", - (u_int) (stb.st_mode & FILEMODEMASK), - (u_long) stb.st_size, last); -#endif + (int64_t)stb.st_size, last); if (verbose_mode) { fprintf(stderr, "Sending file modes: %s", buf); } - (void) atomicio(write, remout, buf, strlen(buf)); + (void) atomicio(vwrite, remout, buf, strlen(buf)); if (response() < 0) goto next; if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) { @@ -587,9 +580,9 @@ next: (void) close(fd); haderr = result >= 0 ? EIO : errno; } if (haderr) - (void) atomicio(write, remout, bp->buf, amt); + (void) atomicio(vwrite, remout, bp->buf, amt); else { - result = atomicio(write, remout, bp->buf, amt); + result = atomicio(vwrite, remout, bp->buf, amt); if (result != amt) haderr = result >= 0 ? EIO : errno; statbytes += result; @@ -603,7 +596,7 @@ next: (void) close(fd); if (close(fd) < 0 && !haderr) haderr = errno; if (!haderr) - (void) atomicio(write, remout, "", 1); + (void) atomicio(vwrite, remout, "", 1); else run_err("%s: %s", name, strerror(haderr)); (void) response(); @@ -611,9 +604,7 @@ next: (void) close(fd); } void -rsource(name, statp) - char *name; - struct stat *statp; +rsource(char *name, struct stat *statp) { DIR *dirp; struct dirent *dp; @@ -632,7 +623,7 @@ rsource(name, statp) (void) snprintf(path, sizeof(path), "T%lu 0 %lu 0\n", (u_long) statp->st_mtime, (u_long) statp->st_atime); - (void) atomicio(write, remout, path, strlen(path)); + (void) atomicio(vwrite, remout, path, strlen(path)); if (response() < 0) { closedir(dirp); return; @@ -642,7 +633,7 @@ rsource(name, statp) (u_int) (statp->st_mode & FILEMODEMASK), 0, last); if (verbose_mode) fprintf(stderr, "Entering directory: %s", path); - (void) atomicio(write, remout, path, strlen(path)); + (void) atomicio(vwrite, remout, path, strlen(path)); if (response() < 0) { closedir(dirp); return; @@ -661,7 +652,7 @@ rsource(name, statp) source(1, vect); } (void) closedir(dirp); - (void) atomicio(write, remout, "E\n", 2); + (void) atomicio(vwrite, remout, "E\n", 2); (void) response(); } @@ -720,9 +711,7 @@ bwlimit(int amount) } void -sink(argc, argv) - int argc; - char *argv[]; +sink(int argc, char **argv) { static BUF buffer; struct stat stb; @@ -753,7 +742,7 @@ sink(argc, argv) if (targetshouldbedirectory) verifydir(targ); - (void) atomicio(write, remout, "", 1); + (void) atomicio(vwrite, remout, "", 1); if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) targisdir = 1; for (first = 1;; first = 0) { @@ -771,7 +760,7 @@ sink(argc, argv) if (buf[0] == '\01' || buf[0] == '\02') { if (iamremote == 0) - (void) atomicio(write, STDERR_FILENO, + (void) atomicio(vwrite, STDERR_FILENO, buf + 1, strlen(buf + 1)); if (buf[0] == '\02') exit(1); @@ -779,7 +768,7 @@ sink(argc, argv) continue; } if (buf[0] == 'E') { - (void) atomicio(write, remout, "", 1); + (void) atomicio(vwrite, remout, "", 1); return; } if (ch == '\n') @@ -801,7 +790,7 @@ sink(argc, argv) atime.tv_usec = strtol(cp, &cp, 10); if (!cp || *cp++ != '\0') SCREWUP("atime.usec not delimited"); - (void) atomicio(write, remout, "", 1); + (void) atomicio(vwrite, remout, "", 1); continue; } if (*cp != 'C' && *cp != 'D') { @@ -886,7 +875,7 @@ sink(argc, argv) bad: run_err("%s: %s", np, strerror(errno)); continue; } - (void) atomicio(write, remout, "", 1); + (void) atomicio(vwrite, remout, "", 1); if ((bp = allocbuf(&buffer, ofd, 4096)) == NULL) { (void) close(ofd); continue; @@ -923,7 +912,7 @@ bad: run_err("%s: %s", np, strerror(errno)); if (count == bp->cnt) { /* Keep reading so we stay sync'd up. */ if (wrerr == NO) { - j = atomicio(write, ofd, bp->buf, count); + j = atomicio(vwrite, ofd, bp->buf, count); if (j != count) { wrerr = YES; wrerrno = j >= 0 ? EIO : errno; @@ -936,7 +925,7 @@ bad: run_err("%s: %s", np, strerror(errno)); if (showprogress) stop_progress_meter(); if (count != 0 && wrerr == NO && - (j = atomicio(write, ofd, bp->buf, count)) != count) { + (j = atomicio(vwrite, ofd, bp->buf, count)) != count) { wrerr = YES; wrerrno = j >= 0 ? EIO : errno; } @@ -981,7 +970,7 @@ bad: run_err("%s: %s", np, strerror(errno)); run_err("%s: %s", np, strerror(wrerrno)); break; case NO: - (void) atomicio(write, remout, "", 1); + (void) atomicio(vwrite, remout, "", 1); break; case DISPLAYED: break; @@ -1016,7 +1005,7 @@ response(void) } while (cp < &rbuf[sizeof(rbuf) - 1] && ch != '\n'); if (!iamremote) - (void) atomicio(write, STDERR_FILENO, rbuf, cp - rbuf); + (void) atomicio(vwrite, STDERR_FILENO, rbuf, cp - rbuf); ++errs; if (resp == 1) return (-1); @@ -1061,8 +1050,7 @@ run_err(const char *fmt,...) } void -verifydir(cp) - char *cp; +verifydir(char *cp) { struct stat stb; @@ -1076,8 +1064,7 @@ verifydir(cp) } int -okname(cp0) - char *cp0; +okname(char *cp0) { int c; char *cp; @@ -1107,9 +1094,7 @@ bad: fprintf(stderr, "%s: invalid user name\n", cp0); } BUF * -allocbuf(bp, fd, blksize) - BUF *bp; - int fd, blksize; +allocbuf(BUF *bp, int fd, int blksize) { size_t size; #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE @@ -1137,8 +1122,7 @@ allocbuf(bp, fd, blksize) } void -lostconn(signo) - int signo; +lostconn(int signo) { if (!iamremote) write(STDERR_FILENO, "lost connection\n", 16); |