File Offsets for SCP (patch)

Bert Wesarg bert.wesarg at googlemail.com
Mon Nov 22 18:52:54 EST 2010


On Fri, Nov 19, 2010 at 21:27, rapier <rapier at psc.edu> wrote:
> I don't know if anyone would be interested in this but I'm including a patch
> to allow for offsets when transferring files with SCP.
>
> It's pretty simple and assumes the user knows what they are doing (for
> example, if transferring with a wild card the offset would apply to all
> files). -A is the number of bytes offset from the beginning of the files. -Z
> is the number of bytes inset from the end of the file.
>
> We may be using this when transferring very large files (100GB+) over
> multiple parallel TCP streams by instantiating multiple SSH connections by
> means of a management application.
>
> Any comments, questions, or suggestions are welcome.
>
>
> --- ../canonical-openssh5.6/scp.c       2010-07-01 23:37:33.000000000 -0400
> +++ scp.c       2010-11-19 17:17:26.000000000 -0500
> @@ -302,6 +302,7 @@ struct passwd *pwd;
>  uid_t userid;
>  int errs, remin, remout;
>  int pflag, iamremote, iamrecursive, targetshouldbedirectory;
> +double fd_offset, fd_inset;
>
>  #define        CMDNEEDS        64
>  char cmd[CMDNEEDS];            /* must hold "rcp -r -p -d\0" */
> @@ -324,6 +325,9 @@ main(int argc, char **argv)
>        extern char *optarg;
>        extern int optind;
>
> +       fd_inset = 0;
> +       fd_offset = 0;
> +
>        /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
>        sanitise_stdfd();
>
> @@ -344,7 +348,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:Z:"))
> != -1)
>                switch (ch) {
>                /* User-visible flags. */
>                case '1':
> @@ -407,6 +411,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 'Z':
> +                       fd_inset = strtod(optarg, &endp);
> +                       if (fd_inset < 0 || *endp != '\0')
> +                                usage();
> +                       break;
>                default:
>                        usage();
>                }
> @@ -680,6 +694,16 @@ syserr:                    run_err("%s: %s", name,
> strerr
>                        run_err("%s: %s", name, "Negative file size");
>                        goto next;
>                }
> +               if (fd_offset > stb.st_size) {
> +                       run_err("Offset greater than file size");
> +                       goto next;
> +               }
> +               if (fd_inset > stb.st_size) {
> +                       run_err("Inset greater than file size");
> +                       goto next;
> +               }
> +               lseek (fd, fd_offset, SEEK_SET);
> +               stb.st_size -= (fd_offset + fd_inset);

What happen if you set fd_offset == fd_inset == stb.st_size?

Bert

>                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