=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/scp.c,v retrieving revision 1.30.2.4 retrieving revision 1.31 diff -u -r1.30.2.4 -r1.31 --- src/usr.bin/ssh/scp.c 2001/03/21 18:53:00 1.30.2.4 +++ src/usr.bin/ssh/scp.c 2000/06/18 03:16:09 1.31 @@ -1,46 +1,16 @@ /* - * scp - secure remote copy. This is basically patched BSD rcp which - * uses ssh to do the data transfer (instead of using rcmd). * - * NOTE: This version should NOT be suid root. (This uses ssh to - * do the transfer and ssh has the necessary privileges.) + * scp - secure remote copy. This is basically patched BSD rcp which uses ssh + * to do the data transfer (instead of using rcmd). * + * NOTE: This version should NOT be suid root. (This uses ssh to do the transfer + * and ssh has the necessary privileges.) + * * 1995 Timo Rinne , Tatu Ylonen * - * As far as I am concerned, the code I have written for this software - * can be used freely for any purpose. Any derived versions of this - * software must be clearly marked as such, and if the derived work is - * incompatible with the protocol description in the RFC file, it must be - * called by a name other than "ssh" or "Secure Shell". - */ -/* - * Copyright (c) 1999 Theo de Raadt. All rights reserved. - * Copyright (c) 1999 Aaron Campbell. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +*/ /* - * Parts from: - * * Copyright (c) 1983, 1990, 1992, 1993, 1995 * The Regents of the University of California. All rights reserved. * @@ -75,13 +45,14 @@ */ #include "includes.h" -RCSID("$OpenBSD: scp.c,v 1.30.2.4 2001/03/21 18:53:00 jason Exp $"); +RCSID("$Id: scp.c,v 1.31 2000/06/18 03:16:09 markus Exp $"); +#include "ssh.h" #include "xmalloc.h" -#include "atomicio.h" -#include "pathnames.h" -#include "log.h" +#include +#define _PATH_CP "cp" + /* For progressmeter() -- number of seconds before xfer considered "stalled" */ #define STALLTIME 5 @@ -90,16 +61,12 @@ /* Returns width of the terminal (for progress meter calculations). */ int getttywidth(void); -int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc); -/* setup arguments for the call to ssh */ -void addargs(char *fmt, ...) __attribute__((format(printf, 1, 2))); - /* Time a transfer started. */ static struct timeval start; /* Number of bytes of current file transferred so far. */ -volatile u_long statbytes; +volatile unsigned long statbytes; /* Total size of current file. */ off_t totalbytes = 0; @@ -107,22 +74,35 @@ /* Name of current file being transferred. */ char *curfile; +/* This is set to non-zero if IPv4 is desired. */ +int IPv4 = 0; + +/* This is set to non-zero if IPv6 is desired. */ +int IPv6 = 0; + /* This is set to non-zero to enable verbose mode. */ int verbose_mode = 0; +/* This is set to non-zero if compression is desired. */ +int compress = 0; + /* This is set to zero if the progressmeter is not desired. */ int showprogress = 1; -/* This is the program to execute for the secured connection. ("ssh" or -S) */ -char *ssh_program = _PATH_SSH_PROGRAM; +/* This is set to non-zero if running in batch mode (that is, password + and passphrase queries are not allowed). */ +int batchmode = 0; -/* This is the list of arguments that scp passes to ssh */ -struct { - char **list; - int num; - int nalloc; -} args; +/* This is set to the cipher type string if given on the command line. */ +char *cipher = NULL; +/* This is set to the RSA authentication identity file name if given on + the command line. */ +char *identity = NULL; + +/* This is the port to use in contacting the remote site (is non-NULL). */ +char *port = NULL; + /* * This function executes the given command as the specified user on the * given host. This returns < 0 if execution fails, and >= 0 otherwise. This @@ -130,13 +110,13 @@ */ int -do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc) +do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout) { int pin[2], pout[2], reserved[2]; if (verbose_mode) - fprintf(stderr, "Executing: program %s host %s, user %s, command %s\n", - ssh_program, host, remuser ? remuser : "(unspecified)", cmd); + fprintf(stderr, "Executing: host %s, user %s, command %s\n", + host, remuser ? remuser : "(unspecified)", cmd); /* * Reserve two descriptors so that the real pipes won't get @@ -155,7 +135,10 @@ close(reserved[1]); /* For a child to execute the command on the remote host using ssh. */ - if (fork() == 0) { + if (fork() == 0) { + char *args[100]; + unsigned int i; + /* Child. */ close(pin[1]); close(pout[0]); @@ -164,14 +147,42 @@ close(pin[0]); close(pout[1]); - args.list[0] = ssh_program; - if (remuser != NULL) - addargs("-l%s", remuser); - addargs("%s", host); - addargs("%s", cmd); + i = 0; + args[i++] = SSH_PROGRAM; + args[i++] = "-x"; + args[i++] = "-oFallBackToRsh no"; + if (IPv4) + args[i++] = "-4"; + if (IPv6) + args[i++] = "-6"; + if (verbose_mode) + args[i++] = "-v"; + if (compress) + args[i++] = "-C"; + if (batchmode) + args[i++] = "-oBatchMode yes"; + if (cipher != NULL) { + args[i++] = "-c"; + args[i++] = cipher; + } + if (identity != NULL) { + args[i++] = "-i"; + args[i++] = identity; + } + if (port != NULL) { + args[i++] = "-p"; + args[i++] = port; + } + if (remuser != NULL) { + args[i++] = "-l"; + args[i++] = remuser; + } + args[i++] = host; + args[i++] = cmd; + args[i++] = NULL; - execvp(ssh_program, args.list); - perror(ssh_program); + execvp(SSH_PROGRAM, args); + perror(SSH_PROGRAM); exit(1); } /* Parent. Close the other side, and return the local side. */ @@ -182,6 +193,21 @@ return 0; } +void +fatal(const char *fmt,...) +{ + va_list ap; + char buf[1024]; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + fprintf(stderr, "%s\n", buf); + exit(255); +} + +/* This stuff used to be in BSD rcp extern.h. */ + typedef struct { int cnt; char *buf; @@ -197,6 +223,8 @@ void run_err(const char *,...); void verifydir(char *); +/* Stuff from BSD rcp.c continues. */ + struct passwd *pwd; uid_t userid; int errs, remin, remout; @@ -205,13 +233,11 @@ #define CMDNEEDS 64 char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */ -int main(int, char *[]); int response(void); void rsource(char *, struct stat *); void sink(int, char *[]); void source(int, char *[]); void tolocal(int, char *[]); -char *cleanhostname(char *); void toremote(char *, int, char *[]); void usage(void); @@ -225,47 +251,25 @@ extern char *optarg; extern int optind; - args.list = NULL; - addargs("ssh"); /* overwritten with ssh_program */ - addargs("-x"); - addargs("-oFallBackToRsh no"); - fflag = tflag = 0; - while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:o:")) != -1) + while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46")) != EOF) switch (ch) { /* User-visible flags. */ case '4': + IPv4 = 1; + break; case '6': - case 'C': - addargs("-%c", ch); + IPv6 = 1; break; - case 'o': - case 'c': - case 'i': - addargs("-%c%s", ch, optarg); - break; - case 'P': - addargs("-p%s", optarg); - break; - case 'B': - addargs("-oBatchmode yes"); - break; case 'p': pflag = 1; break; + case 'P': + port = optarg; + break; case 'r': iamrecursive = 1; break; - case 'S': - ssh_program = xstrdup(optarg); - break; - case 'v': - verbose_mode = 1; - break; - case 'q': - showprogress = 0; - break; - /* Server options. */ case 'd': targetshouldbedirectory = 1; @@ -278,6 +282,24 @@ iamremote = 1; tflag = 1; break; + case 'c': + cipher = optarg; + break; + case 'i': + identity = optarg; + break; + case 'v': + verbose_mode = 1; + break; + case 'B': + batchmode = 1; + break; + case 'C': + compress = 1; + break; + case 'q': + showprogress = 0; + break; case '?': default: usage(); @@ -294,7 +316,7 @@ remin = STDIN_FILENO; remout = STDOUT_FILENO; - if (fflag) { + if (fflag) { /* Follow "protocol", send data. */ (void) response(); source(argc, argv); @@ -312,10 +334,9 @@ remin = remout = -1; /* Command to be executed on remote system using "ssh". */ - (void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s", - verbose_mode ? " -v" : "", - iamrecursive ? " -r" : "", pflag ? " -p" : "", - targetshouldbedirectory ? " -d" : ""); + (void) sprintf(cmd, "scp%s%s%s%s", verbose_mode ? " -v" : "", + iamrecursive ? " -r" : "", pflag ? " -p" : "", + targetshouldbedirectory ? " -d" : ""); (void) signal(SIGPIPE, lostconn); @@ -372,9 +393,9 @@ if (*src == 0) src = "."; host = strchr(argv[i], '@'); - len = strlen(ssh_program) + strlen(argv[i]) + - strlen(src) + (tuser ? strlen(tuser) : 0) + - strlen(thost) + strlen(targ) + CMDNEEDS + 32; + len = strlen(SSH_PROGRAM) + strlen(argv[i]) + + strlen(src) + (tuser ? strlen(tuser) : 0) + + strlen(thost) + strlen(targ) + CMDNEEDS + 32; bp = xmalloc(len); if (host) { *host++ = 0; @@ -384,22 +405,20 @@ suser = pwd->pw_name; else if (!okname(suser)) continue; - snprintf(bp, len, - "%s%s -x -o'FallBackToRsh no' -n " - "-l %s %s %s %s '%s%s%s:%s'", - ssh_program, verbose_mode ? " -v" : "", - suser, host, cmd, src, - tuser ? tuser : "", tuser ? "@" : "", - thost, targ); + (void) sprintf(bp, + "%s%s -x -o'FallBackToRsh no' -n -l %s %s %s %s '%s%s%s:%s'", + SSH_PROGRAM, verbose_mode ? " -v" : "", + suser, host, cmd, src, + tuser ? tuser : "", tuser ? "@" : "", + thost, targ); } else { host = cleanhostname(argv[i]); - snprintf(bp, len, - "exec %s%s -x -o'FallBackToRsh no' -n %s " - "%s %s '%s%s%s:%s'", - ssh_program, verbose_mode ? " -v" : "", - host, cmd, src, - tuser ? tuser : "", tuser ? "@" : "", - thost, targ); + (void) sprintf(bp, + "exec %s%s -x -o'FallBackToRsh no' -n %s %s %s '%s%s%s:%s'", + SSH_PROGRAM, verbose_mode ? " -v" : "", + host, cmd, src, + tuser ? tuser : "", tuser ? "@" : "", + thost, targ); } if (verbose_mode) fprintf(stderr, "Executing: %s\n", bp); @@ -409,10 +428,10 @@ if (remin == -1) { len = strlen(targ) + CMDNEEDS + 20; bp = xmalloc(len); - (void) snprintf(bp, len, "%s -t %s", cmd, targ); + (void) sprintf(bp, "%s -t %s", cmd, targ); host = cleanhostname(thost); - if (do_cmd(host, tuser, bp, &remin, - &remout, argc) < 0) + if (do_cmd(host, tuser, + bp, &remin, &remout) < 0) exit(1); if (response() < 0) exit(1); @@ -434,11 +453,11 @@ for (i = 0; i < argc - 1; i++) { if (!(src = colon(argv[i]))) { /* Local to local. */ len = strlen(_PATH_CP) + strlen(argv[i]) + - strlen(argv[argc - 1]) + 20; + strlen(argv[argc - 1]) + 20; bp = xmalloc(len); - (void) snprintf(bp, len, "exec %s%s%s %s %s", _PATH_CP, - iamrecursive ? " -r" : "", pflag ? " -p" : "", - argv[i], argv[argc - 1]); + (void) sprintf(bp, "exec %s%s%s %s %s", _PATH_CP, + iamrecursive ? " -r" : "", pflag ? " -p" : "", + argv[i], argv[argc - 1]); if (verbose_mode) fprintf(stderr, "Executing: %s\n", bp); if (system(bp)) @@ -463,8 +482,8 @@ host = cleanhostname(host); len = strlen(src) + CMDNEEDS + 20; bp = xmalloc(len); - (void) snprintf(bp, len, "%s -f %s", cmd, src); - if (do_cmd(host, suser, bp, &remin, &remout, argc) < 0) { + (void) sprintf(bp, "%s -f %s", cmd, src); + if (do_cmd(host, suser, bp, &remin, &remout) < 0) { (void) xfree(bp); ++errs; continue; @@ -520,17 +539,18 @@ * Make it compatible with possible future * versions expecting microseconds. */ - (void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n", - (u_long) stb.st_mtime, - (u_long) stb.st_atime); + (void) sprintf(buf, "T%lu 0 %lu 0\n", + (unsigned long) stb.st_mtime, + (unsigned long) stb.st_atime); (void) atomicio(write, remout, buf, strlen(buf)); if (response() < 0) goto next; } #define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) - snprintf(buf, sizeof buf, "C%04o %lld %s\n", - (u_int) (stb.st_mode & FILEMODEMASK), - stb.st_size, last); + (void) sprintf(buf, "C%04o %lu %s\n", + (unsigned int) (stb.st_mode & FILEMODEMASK), + (unsigned long) stb.st_size, + last); if (verbose_mode) { fprintf(stderr, "Sending file modes: %s", buf); fflush(stderr); @@ -597,17 +617,18 @@ else last++; if (pflag) { - (void) snprintf(path, sizeof(path), "T%lu 0 %lu 0\n", - (u_long) statp->st_mtime, - (u_long) statp->st_atime); + (void) sprintf(path, "T%lu 0 %lu 0\n", + (unsigned long) statp->st_mtime, + (unsigned long) statp->st_atime); (void) atomicio(write, remout, path, strlen(path)); if (response() < 0) { closedir(dirp); return; } } - (void) snprintf(path, sizeof path, "D%04o %d %.1024s\n", - (u_int) (statp->st_mode & FILEMODEMASK), 0, last); + (void) sprintf(path, "D%04o %d %.1024s\n", + (unsigned int) (statp->st_mode & FILEMODEMASK), + 0, last); if (verbose_mode) fprintf(stderr, "Entering directory: %s", path); (void) atomicio(write, remout, path, strlen(path)); @@ -624,7 +645,7 @@ run_err("%s/%s: name too long", name, dp->d_name); continue; } - (void) snprintf(path, sizeof path, "%s/%s", name, dp->d_name); + (void) sprintf(path, "%s/%s", name, dp->d_name); vect[0] = path; source(1, vect); } @@ -646,11 +667,10 @@ BUF *bp; off_t i, j; int amt, count, exists, first, mask, mode, ofd, omode; - off_t size; - int setimes, targisdir, wrerrno = 0; + int setimes, size, targisdir, wrerrno = 0; char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; + struct utimbuf ut; int dummy_usec; - struct timeval tv[2]; #define SCREWUP(str) { why = str; goto screwup; } @@ -685,7 +705,7 @@ if (buf[0] == '\01' || buf[0] == '\02') { if (iamremote == 0) (void) atomicio(write, STDERR_FILENO, - buf + 1, strlen(buf + 1)); + buf + 1, strlen(buf + 1)); if (buf[0] == '\02') exit(1); ++errs; @@ -704,18 +724,16 @@ if (*cp == 'T') { setimes++; cp++; - getnum(tv[1].tv_sec); + getnum(ut.modtime); if (*cp++ != ' ') SCREWUP("mtime.sec not delimited"); getnum(dummy_usec); - tv[1].tv_usec = 0; if (*cp++ != ' ') SCREWUP("mtime.usec not delimited"); - getnum(tv[0].tv_sec); + getnum(ut.actime); if (*cp++ != ' ') SCREWUP("atime.sec not delimited"); getnum(dummy_usec); - tv[0].tv_usec = 0; if (*cp++ != '\0') SCREWUP("atime.usec not delimited"); (void) atomicio(write, remout, "", 1); @@ -754,14 +772,10 @@ size_t need; need = strlen(targ) + strlen(cp) + 250; - if (need > cursize) { - if (namebuf) - xfree(namebuf); + if (need > cursize) namebuf = xmalloc(need); - cursize = need; - } - (void) snprintf(namebuf, need, "%s%s%s", targ, - *targ ? "/" : "", cp); + (void) sprintf(namebuf, "%s%s%s", targ, + *targ ? "/" : "", cp); np = namebuf; } else np = targ; @@ -783,18 +797,16 @@ if (mkdir(np, mode | S_IRWXU) < 0) goto bad; } - vect[0] = xstrdup(np); + vect[0] = np; sink(1, vect); if (setimes) { setimes = 0; - if (utimes(vect[0], tv) < 0) + if (utime(np, &ut) < 0) run_err("%s: set times: %s", - vect[0], strerror(errno)); + np, strerror(errno)); } if (mod_flag) - (void) chmod(vect[0], mode); - if (vect[0]) - xfree(vect[0]); + (void) chmod(np, mode); continue; } omode = mode; @@ -822,10 +834,8 @@ amt = size - i; count += amt; do { - j = read(remin, cp, amt); - if (j == -1 && (errno == EINTR || errno == EAGAIN)) { - continue; - } else if (j <= 0) { + j = atomicio(read, remin, cp, amt); + if (j <= 0) { run_err("%s", j ? strerror(errno) : "dropped connection"); exit(1); @@ -871,14 +881,11 @@ run_err("%s: set mode: %s", np, strerror(errno)); } - if (close(ofd) == -1) { - wrerr = YES; - wrerrno = errno; - } + (void) close(ofd); (void) response(); if (setimes && wrerr == NO) { setimes = 0; - if (utimes(np, tv) < 0) { + if (utime(np, &ut) < 0) { run_err("%s: set times: %s", np, strerror(errno)); wrerr = DISPLAYED; @@ -936,9 +943,8 @@ void usage() { - (void) fprintf(stderr, "usage: scp " - "[-pqrvC46] [-S ssh] [-P port] [-c cipher] [-i identity] f1 f2; or:\n" - " scp [options] f1 ... fn directory\n"); + (void) fprintf(stderr, + "usage: scp [-pqrvC46] [-P port] [-c cipher] [-i identity] f1 f2; or:\n scp [options] f1 ... fn directory\n"); exit(1); } @@ -965,6 +971,43 @@ va_end(ap); } +/* Stuff below is from BSD rcp util.c. */ + +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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 + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: scp.c,v 1.31 2000/06/18 03:16:09 markus Exp $ + */ + char * colon(cp) char *cp; @@ -1016,8 +1059,7 @@ c = *cp; if (c & 0200) goto bad; - if (!isalpha(c) && !isdigit(c) && - c != '_' && c != '-' && c != '.' && c != '+') + if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-' && c != '.') goto bad; } while (*++cp); return (1); @@ -1042,7 +1084,7 @@ size = blksize; else size = blksize + (stb.st_blksize - blksize % stb.st_blksize) % - stb.st_blksize; + stb.st_blksize; if (bp->cnt >= size) return (bp); if (bp->buf == NULL) @@ -1084,7 +1126,7 @@ } int -foregroundproc(void) +foregroundproc() { static pid_t pgrp = -1; int ctty_pgrp; @@ -1131,10 +1173,10 @@ if (barlength > 0) { i = barlength * ratio / 100; snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - "|%.*s%*s|", i, - "*****************************************************************************" - "*****************************************************************************", - barlength - i, ""); + "|%.*s%*s|", i, + "*****************************************************************************" + "*****************************************************************************", + barlength - i, ""); } i = 0; abbrevsize = cursize; @@ -1142,9 +1184,9 @@ i++; abbrevsize >>= 10; } - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %5llu %c%c ", - (unsigned long long) abbrevsize, prefixes[i], - prefixes[i] == ' ' ? ' ' : 'B'); + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %5qd %c%c ", + (quad_t) abbrevsize, prefixes[i], prefixes[i] == ' ' ? ' ' : + 'B'); timersub(&now, &lastupdate, &wait); if (cursize > lastsize) { @@ -1159,31 +1201,30 @@ timersub(&now, &start, &td); elapsed = td.tv_sec + (td.tv_usec / 1000000.0); - if (flag != 1 && - (statbytes <= 0 || elapsed <= 0.0 || cursize > totalbytes)) { + if (statbytes <= 0 || elapsed <= 0.0 || cursize > totalbytes) { snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - " --:-- ETA"); + " --:-- ETA"); } else if (wait.tv_sec >= STALLTIME) { snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - " - stalled -"); + " - stalled -"); } else { if (flag != 1) - remaining = (int)(totalbytes / (statbytes / elapsed) - - elapsed); + remaining = + (int)(totalbytes / (statbytes / elapsed) - elapsed); else remaining = elapsed; i = remaining / 3600; if (i) snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - "%2d:", i); + "%2d:", i); else snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - " "); + " "); i = remaining % 3600; snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - "%02d:%02d%s", i / 60, i % 60, - (flag != 1) ? " ETA" : " "); + "%02d:%02d%s", i / 60, i % 60, + (flag != 1) ? " ETA" : " "); } atomicio(write, fileno(stdout), buf, strlen(buf)); @@ -1206,26 +1247,4 @@ return (winsize.ws_col ? winsize.ws_col : 80); else return (80); -} - -void -addargs(char *fmt, ...) -{ - va_list ap; - char buf[1024]; - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - - if (args.list == NULL) { - args.nalloc = 32; - args.num = 0; - args.list = xmalloc(args.nalloc * sizeof(char *)); - } else if (args.num+2 >= args.nalloc) { - args.nalloc *= 2; - args.list = xrealloc(args.list, args.nalloc * sizeof(char *)); - } - args.list[args.num++] = xstrdup(buf); - args.list[args.num] = NULL; }