=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/scp.c,v retrieving revision 1.102 retrieving revision 1.102.2.2 diff -u -r1.102 -r1.102.2.2 --- src/usr.bin/ssh/scp.c 2003/03/05 22:33:43 1.102 +++ src/usr.bin/ssh/scp.c 2004/03/04 18:18:16 1.102.2.2 @@ -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.102.2.2 2004/03/04 18:18:16 brad Exp $"); #include "xmalloc.h" #include "atomicio.h" @@ -92,7 +88,7 @@ arglist args; /* Bandwidth limit */ -off_t limit = 0; +off_t limit_rate = 0; /* Name of current file being transferred. */ char *curfile; @@ -107,8 +103,17 @@ 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 * given host. This returns < 0 if execution fails, and >= 0 otherwise. This @@ -142,7 +147,7 @@ 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. */ @@ -170,6 +175,9 @@ *fdout = pin[1]; close(pout[1]); *fdin = pout[0]; + signal(SIGTERM, killchild); + signal(SIGINT, killchild); + signal(SIGHUP, killchild); return 0; } @@ -202,9 +210,7 @@ void usage(void); int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char **argv) { int ch, fflag, tflag, status; double speed; @@ -245,7 +251,7 @@ speed = strtod(optarg, &endp); if (speed <= 0 || *endp != '\0') usage(); - limit = speed * 1024; + limit_rate = speed * 1024; break; case 'p': pflag = 1; @@ -261,6 +267,7 @@ verbose_mode = 1; break; case 'q': + addargs(&args, "-q"); showprogress = 0; break; @@ -283,7 +290,7 @@ 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; @@ -344,9 +351,7 @@ } 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; @@ -413,7 +418,8 @@ } if (verbose_mode) fprintf(stderr, "Executing: %s\n", bp); - (void) system(bp); + if (system(bp) != 0) + errs = 1; (void) xfree(bp); } else { /* local to remote */ if (remin == -1) { @@ -434,9 +440,7 @@ } void -tolocal(argc, argv) - int argc; - char *argv[]; +tolocal(int argc, char **argv) { int i, len; char *bp, *host, *src, *suser; @@ -485,9 +489,7 @@ } void -source(argc, argv) - int argc; - char *argv[]; +source(int argc, char **argv) { struct stat stb; static BUF buffer; @@ -540,7 +542,7 @@ (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; } @@ -551,7 +553,7 @@ 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) { @@ -571,14 +573,14 @@ 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; } - if (limit) + if (limit_rate) bwlimit(amt); } if (showprogress) @@ -587,7 +589,7 @@ 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(); @@ -595,9 +597,7 @@ } void -rsource(name, statp) - char *name; - struct stat *statp; +rsource(char *name, struct stat *statp) { DIR *dirp; struct dirent *dp; @@ -616,7 +616,7 @@ (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; @@ -626,7 +626,7 @@ (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; @@ -645,7 +645,7 @@ source(1, vect); } (void) closedir(dirp); - (void) atomicio(write, remout, "E\n", 2); + (void) atomicio(vwrite, remout, "E\n", 2); (void) response(); } @@ -672,7 +672,7 @@ return; lamt *= 8; - wait = (double)1000000L * lamt / limit; + wait = (double)1000000L * lamt / limit_rate; bwstart.tv_sec = wait / 1000000L; bwstart.tv_usec = wait % 1000000L; @@ -704,9 +704,7 @@ } void -sink(argc, argv) - int argc; - char *argv[]; +sink(int argc, char **argv) { static BUF buffer; struct stat stb; @@ -737,7 +735,7 @@ 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) { @@ -755,7 +753,7 @@ 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); @@ -763,7 +761,7 @@ continue; } if (buf[0] == 'E') { - (void) atomicio(write, remout, "", 1); + (void) atomicio(vwrite, remout, "", 1); return; } if (ch == '\n') @@ -785,7 +783,7 @@ 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') { @@ -870,7 +868,7 @@ 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; @@ -900,14 +898,14 @@ cp += j; statbytes += j; } while (amt > 0); - - if (limit) + + if (limit_rate) bwlimit(4096); 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; @@ -920,7 +918,7 @@ 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; } @@ -957,7 +955,7 @@ run_err("%s: %s", np, strerror(wrerrno)); break; case NO: - (void) atomicio(write, remout, "", 1); + (void) atomicio(vwrite, remout, "", 1); break; case DISPLAYED: break; @@ -992,7 +990,7 @@ } 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); @@ -1005,8 +1003,8 @@ usage(void) { (void) fprintf(stderr, - "usage: scp [-pqrvBC1246] [-F config] [-S program] [-P port]\n" - " [-c cipher] [-i identity] [-l limit] [-o option]\n" + "usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n" + " [-l limit] [-o ssh_option] [-P port] [-S program]\n" " [[user@]host1:]file1 [...] [[user@]host2:]file2\n"); exit(1); } @@ -1037,8 +1035,7 @@ } void -verifydir(cp) - char *cp; +verifydir(char *cp) { struct stat stb; @@ -1052,8 +1049,7 @@ } int -okname(cp0) - char *cp0; +okname(char *cp0) { int c; char *cp; @@ -1083,9 +1079,7 @@ } BUF * -allocbuf(bp, fd, blksize) - BUF *bp; - int fd, blksize; +allocbuf(BUF *bp, int fd, int blksize) { size_t size; struct stat stb; @@ -1109,8 +1103,7 @@ } void -lostconn(signo) - int signo; +lostconn(int signo) { if (!iamremote) write(STDERR_FILENO, "lost connection\n", 16);