File Offsets for SCP (patch)
rapier
rapier at psc.edu
Sat Nov 20 07:27:34 EST 2010
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);
unset_nonblock(fd);
switch (stb.st_mode & S_IFMT) {
case S_IFREG:
More information about the openssh-unix-dev
mailing list