File Offsets for SCP (patch revised yet again)

rapier rapier at psc.edu
Tue Dec 7 09:03:56 EST 2010


This version of the patch now does partial file transfers in both 
directions. -A specifies the start byte -L the length. As systems might 
have the patched scp running as a secondary server I have also include a 
method to provide a path to the desired scp executable using the -a option.

Again, I don't know if this will be useful to anyone else. We're going 
to be using this to do parallelized transfers of large (250GB+) files 
(using the HPN patch set as well). We're basically trying to avoid the 
slow start penalties on very fast throughputs by splitting the transfer up.

I know scp is no longer supported in anyway except to maintain the 
versioning. Unfortunately, a huge number of people still use scp in 
preference to scp. I'm an enabler. :\

chris



rapier wrote:
> Just a follow up patch. You now just specify the byte length you want to 
> transfer and a little more error checking. Again, don't know if this 
> would be useful to anyone but I thought I'd share just in case. Also, 
> just to make sure this is clear, this only works on the source side.
> 
> --- ../canonical-openssh5.6/scp.c    2010-07-01 23:37:33.000000000 -0400
> +++ ./scp.c    2010-11-22 19:48:46.000000000 -0500
> @@ -302,6 +302,8 @@ struct passwd *pwd;
>  uid_t userid;
>  int errs, remin, remout;
>  int pflag, iamremote, iamrecursive, targetshouldbedirectory;
> +// user requested file offset and amount of data to xfer
> +double fd_offset, fd_length;
> 
>  #define    CMDNEEDS    64
>  char cmd[CMDNEEDS];        /* must hold "rcp -r -p -d\0" */
> @@ -324,6 +326,9 @@ main(int argc, char **argv)
>      extern char *optarg;
>      extern int optind;
> 
> +    fd_length = 0;
> +    fd_offset = 0;
> +
>      /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
>      sanitise_stdfd();
> 
> @@ -344,7 +349,7 @@ main(int argc, char **argv)
>      addargs(&args, "-oClearAllForwardings yes");
> 
>      fflag = tflag = 0;
> -    while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1)
> +    while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:A:L:")) 
> != -1)
>          switch (ch) {
>          /* User-visible flags. */
>          case '1':
> @@ -407,6 +412,16 @@ main(int argc, char **argv)
>              setmode(0, O_BINARY);
>  #endif
>              break;
> +        case 'A':
> +            fd_offset = strtod(optarg, &endp);
> +            if (fd_offset < 0 || *endp != '\0')
> +                                usage();
> +            break;
> +        case 'L':
> +            fd_length = strtod(optarg, &endp);
> +            if (fd_length < 0 || *endp != '\0')
> +                                usage();
> +            break;
>          default:
>              usage();
>          }
> @@ -680,6 +695,34 @@ syserr:            run_err("%s: %s", name, strerr
>              run_err("%s: %s", name, "Negative file size");
>              goto next;
>          }
> +
> +        // if the offset is greater than the file size
> +        // we can't do this
> +        if (fd_offset > stb.st_size) {
> +            run_err("Offset greater than file size");
> +            goto next;
> +        }
> +       
> +        // if the offset plus the requested length are greater
> +        // than the file size then we have to quit
> +        if (fd_length + fd_offset > stb.st_size) {
> +            run_err("Length greater than file size");
> +            goto next;
> +        }
> +
> +        // if the user only has an offset then we reduce
> +        // the file size by the offset. if they have a length
> +        // then we use stb.st_size and the length
> +        // to determine the actual stopping point
> +        if (fd_length != 0) {
> +            stb.st_size -= (stb.st_size - fd_length);
> +        } else {
> +            stb.st_size -= fd_offset;
> +        }
> +       
> +        // seek to the position as requested by user
> +        lseek (fd, fd_offset, SEEK_SET);
> +
>          unset_nonblock(fd);
>          switch (stb.st_mode & S_IFMT) {
>          case S_IFREG:
> 
> 
> 
> _______________________________________________
> openssh-unix-dev mailing list
> openssh-unix-dev at mindrot.org
> https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev


More information about the openssh-unix-dev mailing list