File Offsets for SCP (patch)

rapier rapier at psc.edu
Tue Nov 23 07:03:05 EST 2010


Good question. I just tested this out. If you set either A or Z to the 
file size then it creates a zero byte file on the remote end. Which is 
exactly what you'd expect. If you set either A or Z greater than the 
file size then you get an error 'Offset greater than file size'. If the 
combination of A and Z are greater than the file size you get a protocol 
error 'scp: protocol error: size not delimited'. So I need to add some 
math in there.


Bert Wesarg wrote:
> 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
>>
> _______________________________________________
> 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