]> andersk Git - openssh.git/blobdiff - scp.c
- Checks for 64 bit int types. Problem report from Mats Fredholm
[openssh.git] / scp.c
diff --git a/scp.c b/scp.c
index aa522d96b05bbbc8ce825129658ee78f18d20a7e..18e2333519d3a6bd2001a0ba29311892d29e8fd9 100644 (file)
--- a/scp.c
+++ b/scp.c
@@ -74,11 +74,17 @@ off_t totalbytes = 0;
 /* 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;
+int compress_flag = 0;
 
 /* This is set to zero if the progressmeter is not desired. */
 int showprogress = 1;
@@ -97,9 +103,11 @@ 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 assigns the input and output file descriptors on success. */
+/*
+ * This function executes the given command as the specified user on the
+ * given host.  This returns < 0 if execution fails, and >= 0 otherwise. This
+ * assigns the input and output file descriptors on success.
+ */
 
 int 
 do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
@@ -110,8 +118,10 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
                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
-          descriptors 0 and 1 because that will screw up dup2 below. */
+       /*
+        * Reserve two descriptors so that the real pipes won't get
+        * descriptors 0 and 1 because that will screw up dup2 below.
+        */
        pipe(reserved);
 
        /* Create a socket pair for communicating with ssh. */
@@ -141,9 +151,14 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
                args[i++] = SSH_PROGRAM;
                args[i++] = "-x";
                args[i++] = "-oFallBackToRsh no";
+               if (IPv4)
+                       args[i++] = "-4";
+               if (IPv6)
+                       args[i++] = "-6";
+               args[i++] = "-oFallBackToRsh no";
                if (verbose_mode)
                        args[i++] = "-v";
-               if (compress)
+               if (compress_flag)
                        args[i++] = "-C";
                if (batchmode)
                        args[i++] = "-oBatchMode yes";
@@ -238,9 +253,15 @@ main(argc, argv)
        extern int optind;
 
        fflag = tflag = 0;
-       while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q")) != EOF)
+       while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46")) != EOF)
                switch (ch) {
                /* User-visible flags. */
+               case '4':
+                       IPv4 = 1;
+                       break;
+               case '6':
+                       IPv6 = 1;
+                       break;
                case 'p':
                        pflag = 1;
                        break;
@@ -275,7 +296,7 @@ main(argc, argv)
                        batchmode = 1;
                        break;
                case 'C':
-                       compress = 1;
+                       compress_flag = 1;
                        break;
                case 'q':
                        showprogress = 0;
@@ -330,6 +351,17 @@ main(argc, argv)
        exit(errs != 0);
 }
 
+char *
+cleanhostname(host)
+       char *host;
+{
+       if (*host == '[' && host[strlen(host) - 1] == ']') {
+               host[strlen(host) - 1] = '\0';
+               return (host + 1);
+       } else
+               return host;
+}
+
 void
 toremote(targ, argc, argv)
        char *targ, *argv[];
@@ -368,6 +400,7 @@ toremote(targ, argc, argv)
                        bp = xmalloc(len);
                        if (host) {
                                *host++ = 0;
+                               host = cleanhostname(host);
                                suser = argv[i];
                                if (*suser == '\0')
                                        suser = pwd->pw_name;
@@ -379,13 +412,15 @@ toremote(targ, argc, argv)
                                               suser, host, cmd, src,
                                               tuser ? tuser : "", tuser ? "@" : "",
                                               thost, targ);
-                       } else
+                       } else {
+                               host = cleanhostname(argv[i]);
                                (void) sprintf(bp,
                                               "exec %s%s -x -o'FallBackToRsh no' -n %s %s %s '%s%s%s:%s'",
                                               SSH_PROGRAM, verbose_mode ? " -v" : "",
-                                              argv[i], cmd, src,
+                                              host, cmd, src,
                                               tuser ? tuser : "", tuser ? "@" : "",
                                               thost, targ);
+                       }
                        if (verbose_mode)
                                fprintf(stderr, "Executing: %s\n", bp);
                        (void) system(bp);
@@ -395,7 +430,7 @@ toremote(targ, argc, argv)
                                len = strlen(targ) + CMDNEEDS + 20;
                                bp = xmalloc(len);
                                (void) sprintf(bp, "%s -t %s", cmd, targ);
-                               host = thost;
+                               host = cleanhostname(thost);
                                if (do_cmd(host, tuser,
                                           bp, &remin, &remout) < 0)
                                        exit(1);
@@ -445,6 +480,7 @@ tolocal(argc, argv)
                        else if (!okname(suser))
                                continue;
                }
+               host = cleanhostname(host);
                len = strlen(src) + CMDNEEDS + 20;
                bp = xmalloc(len);
                (void) sprintf(bp, "%s -f %s", cmd, src);
@@ -544,7 +580,7 @@ next:                       (void) close(fd);
                        if (haderr)
                                (void) write(remout, bp->buf, amt);
                        else {
-                               result = write(remout, bp->buf, amt);
+                               result = atomicio(write, remout, bp->buf, amt);
                                if (result != amt)
                                        haderr = result >= 0 ? EIO : errno;
                                statbytes += result;
@@ -909,7 +945,7 @@ void
 usage()
 {
        (void) fprintf(stderr,
-                      "usage: scp [-pqrvC] [-P port] [-c cipher] [-i identity] f1 f2; or:\n       scp [options] f1 ... fn directory\n");
+                      "usage: scp [-pqrvC46] [-P port] [-c cipher] [-i identity] f1 f2; or:\n       scp [options] f1 ... fn directory\n");
        exit(1);
 }
 
@@ -918,22 +954,24 @@ run_err(const char *fmt,...)
 {
        static FILE *fp;
        va_list ap;
-       va_start(ap, fmt);
 
        ++errs;
        if (fp == NULL && !(fp = fdopen(remout, "w")))
                return;
        (void) fprintf(fp, "%c", 0x01);
        (void) fprintf(fp, "scp: ");
+       va_start(ap, fmt);
        (void) vfprintf(fp, fmt, ap);
+       va_end(ap);
        (void) fprintf(fp, "\n");
        (void) fflush(fp);
 
        if (!iamremote) {
+               va_start(ap, fmt);
                vfprintf(stderr, fmt, ap);
+               va_end(ap);
                fprintf(stderr, "\n");
        }
-       va_end(ap);
 }
 
 /* Stuff below is from BSD rcp util.c. */
@@ -977,11 +1015,19 @@ char *
 colon(cp)
        char *cp;
 {
+       int flag = 0;
+
        if (*cp == ':')         /* Leading colon is part of file name. */
                return (0);
+       if (*cp == '[')
+               flag = 1;
 
        for (; *cp; ++cp) {
-               if (*cp == ':')
+               if (*cp == '@' && *(cp+1) == '[')
+                       flag = 1;
+               if (*cp == ']' && *(cp+1) == ':' && flag)
+                       return (cp+1);
+               if (*cp == ':' && !flag)
                        return (cp);
                if (*cp == '/')
                        return (0);
@@ -1021,7 +1067,7 @@ okname(cp0)
        } while (*++cp);
        return (1);
 
-bad:   fprintf(stderr, "%s: invalid user name", cp0);
+bad:   fprintf(stderr, "%s: invalid user name\n", cp0);
        return (0);
 }
 
@@ -1061,30 +1107,6 @@ lostconn(signo)
        exit(1);
 }
 
-/*
- * ensure all of data on socket comes through. f==read || f==write
- */
-int
-atomicio(f, fd, s, n)
-       int (*f) ();
-       char *s;
-{
-       int res, pos = 0;
-
-       while (n > pos) {
-               res = (f) (fd, s + pos, n - pos);
-               switch (res) {
-               case -1:
-                       if (errno == EINTR || errno == EAGAIN)
-                               continue;
-               case 0:
-                       return (res);
-               default:
-                       pos += res;
-               }
-       }
-       return (pos);
-}
 
 void
 alarmtimer(int wait)
@@ -1098,7 +1120,7 @@ alarmtimer(int wait)
 }
 
 void
-updateprogressmeter(void)
+updateprogressmeter(int sig)
 {
        int save_errno = errno;
 
@@ -1142,7 +1164,7 @@ progressmeter(int flag)
        (void) gettimeofday(&now, (struct timezone *) 0);
        cursize = statbytes;
        if (totalbytes != 0) {
-               ratio = cursize * 100.0 / totalbytes;
+               ratio = 100.0 * cursize / totalbytes;
                ratio = MAX(ratio, 0);
                ratio = MIN(ratio, 100);
        } else
@@ -1165,8 +1187,8 @@ progressmeter(int flag)
                i++;
                abbrevsize >>= 10;
        }
-       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %5qd %c%c ",
-            (quad_t) abbrevsize, prefixes[i], prefixes[i] == ' ' ? ' ' :
+       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %5d %c%c ",
+            (int) abbrevsize, prefixes[i], prefixes[i] == ' ' ? ' ' :
                 'B');
 
        timersub(&now, &lastupdate, &wait);
@@ -1204,7 +1226,11 @@ progressmeter(int flag)
        atomicio(write, fileno(stdout), buf, strlen(buf));
 
        if (flag == -1) {
-               signal(SIGALRM, (void *) updateprogressmeter);
+               struct sigaction sa;
+               sa.sa_handler = updateprogressmeter;
+               sigemptyset(&sa.sa_mask);
+               sa.sa_flags = SA_RESTART;
+               sigaction(SIGALRM, &sa, NULL);
                alarmtimer(1);
        } else if (flag == 1) {
                alarmtimer(0);
This page took 0.04707 seconds and 4 git commands to generate.