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