From 143990da3463f14aed25e14806d508872ecc97c5 Mon Sep 17 00:00:00 2001 From: Russ Magee Date: Thu, 30 Aug 2018 20:06:42 -0700 Subject: [PATCH] Scatter/gather for client->server copy now functional --- hkexsh/hkexsh.go | 17 ++++++++++++++--- hkexshd/hkexshd.go | 15 +++------------ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/hkexsh/hkexsh.go b/hkexsh/hkexsh.go index e646768..0e37a1e 100755 --- a/hkexsh/hkexsh.go +++ b/hkexsh/hkexsh.go @@ -16,6 +16,7 @@ import ( "os" "os/exec" "os/user" + "path" "runtime" "strings" "sync" @@ -106,10 +107,20 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *cmdSpec) //os.Setenv("TERM", "vt102") // TODO: server or client option? cmdName := "/bin/tar" - cmdArgs := []string{"-c", "-f", "/dev/stdout"} + cmdArgs := []string{"-cz", "-f", "/dev/stdout"} files = strings.TrimSpace(files) + // Awesome fact: tar actually can take multiple -C args, and + // changes to the dest dir *as it sees each one*. This enables + // its use below, where clients can send scattered sets of source + // files and dirs to be extraced to a single dest dir server-side, + // whilst preserving the subtrees of dirs on the other side. :) + // Eg., tar -c -f /dev/stdout -C /dirA fileInA -C /some/where/dirB fileInB /foo/dirC + // packages fileInA, fileInB, and dirC at a single toplevel in the tar. + // The tar authors are/were real smarties :) for _, v := range strings.Split(files, " ") { - cmdArgs = append(cmdArgs, v) + dirTmp, fileTmp := path.Split(v) + cmdArgs = append(cmdArgs, "-C", dirTmp, fileTmp) + //cmdArgs = append(cmdArgs, v) } fmt.Printf("[%v %v]\n", cmdName, cmdArgs) @@ -160,7 +171,7 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *cmdSpec) cmdName := "/bin/tar" destPath := files - cmdArgs := []string{"-x", "-C", destPath} + cmdArgs := []string{"-xz", "-C", destPath} fmt.Printf("[%v %v]\n", cmdName, cmdArgs) // NOTE the lack of quotes around --xform option's sed expression. // When args are passed in exec() format, no quoting is required diff --git a/hkexshd/hkexshd.go b/hkexshd/hkexshd.go index 07a7251..9832bdf 100755 --- a/hkexshd/hkexshd.go +++ b/hkexshd/hkexshd.go @@ -66,22 +66,13 @@ func runClientToServerCopyAs(who string, conn hkexnet.Conn, fpath string, chaffi } else { destDir = path.Join(u.HomeDir, fpath) } - //stat, pe := os.Stat(destDir) - //_ = stat - //if pe != nil { - // log.Fatal(pe) - // return pe, 252 // ?! - //} - //if stat.IsDir(destBase) { - cmdArgs := []string{"-x", "-C", destDir} - //} else { - // cmdArgs := []string{"-x", + cmdArgs := []string{"-xz", "-C", destDir} // NOTE the lack of quotes around --xform option's sed expression. // When args are passed in exec() format, no quoting is required // (as this isn't input from a shell) (right? -rlm 20180823) - //cmdArgs := []string{"-xvz", "-C", destPath, `--xform=s#.*/\(.*\)#\1#`} + //cmdArgs := []string{"-x", "-C", destDir, `--xform=s#.*/\(.*\)#\1#`} c = exec.Command(cmdName, cmdArgs...) c.Dir = destDir @@ -152,7 +143,7 @@ func runServerToClientCopyAs(who string, conn hkexnet.Conn, srcPath string, chaf cmdName := "/bin/tar" //cmdArgs := []string{"-c", "-f", "-", srcPath} srcDir, srcBase := path.Split(srcPath) - cmdArgs := []string{"-c", "-C", srcDir, "-f", "-", srcBase} + cmdArgs := []string{"-cz", "-C", srcDir, "-f", "-", srcBase} c = exec.Command(cmdName, cmdArgs...)