mirror of
https://gogs.blitter.com/RLabs/xs
synced 2024-08-14 10:26:42 +00:00
Fixed errors in copy scatter/gather logic. Added block-chunking to hc.Write() to allow
writes of larger data blocks TODO: copies of files > hc.Read() block size fails w/incomplete tarfile (last partial block likely incorrectly written or client exits before data is flushed?)
This commit is contained in:
parent
022db4956c
commit
52ea229118
3 changed files with 27 additions and 14 deletions
|
@ -394,7 +394,7 @@ func (hc Conn) Read(b []byte) (n int, err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if payloadLen > 16384 {
|
if payloadLen > 8192 {
|
||||||
log.Printf("[Insane payloadLen:%v]\n", payloadLen)
|
log.Printf("[Insane payloadLen:%v]\n", payloadLen)
|
||||||
hc.Close()
|
hc.Close()
|
||||||
return 1, errors.New("Insane payloadLen")
|
return 1, errors.New("Insane payloadLen")
|
||||||
|
@ -499,13 +499,15 @@ func (hc Conn) WritePacket(b []byte, op byte) (n int, err error) {
|
||||||
// Would be nice to determine if the mutex scope
|
// Would be nice to determine if the mutex scope
|
||||||
// could be tightened.
|
// could be tightened.
|
||||||
hc.m.Lock()
|
hc.m.Lock()
|
||||||
{
|
for uint32(len(b)) > 0 {
|
||||||
log.Printf(" :>ptext:\r\n%s\r\n", hex.Dump(b))
|
|
||||||
|
|
||||||
payloadLen = uint32(len(b))
|
payloadLen = uint32(len(b))
|
||||||
|
if payloadLen > 8192 {
|
||||||
|
payloadLen = 8192
|
||||||
|
}
|
||||||
|
log.Printf(" :>ptext:\r\n%s\r\n", hex.Dump(b[0:payloadLen]))
|
||||||
|
|
||||||
// Calculate hmac on payload
|
// Calculate hmac on payload
|
||||||
hc.wm.Write(b)
|
hc.wm.Write(b[0:payloadLen])
|
||||||
hmacOut = hc.wm.Sum(nil)[0:4]
|
hmacOut = hc.wm.Sum(nil)[0:4]
|
||||||
|
|
||||||
log.Printf(" (%04x> HMAC(o):%s\r\n", payloadLen, hex.EncodeToString(hmacOut))
|
log.Printf(" (%04x> HMAC(o):%s\r\n", payloadLen, hex.EncodeToString(hmacOut))
|
||||||
|
@ -514,14 +516,13 @@ func (hc Conn) WritePacket(b []byte, op byte) (n int, err error) {
|
||||||
// The StreamWriter acts like a pipe, forwarding whatever is
|
// The StreamWriter acts like a pipe, forwarding whatever is
|
||||||
// written to it through the cipher, encrypting as it goes
|
// written to it through the cipher, encrypting as it goes
|
||||||
ws := &cipher.StreamWriter{S: hc.w, W: &wb}
|
ws := &cipher.StreamWriter{S: hc.w, W: &wb}
|
||||||
_, err = ws.Write(b)
|
_, err = ws.Write(b[0:payloadLen])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
log.Printf(" ->ctext:\r\n%s\r\n", hex.Dump(wb.Bytes()))
|
log.Printf(" ->ctext:\r\n%s\r\n", hex.Dump(wb.Bytes()))
|
||||||
|
|
||||||
ctrlStatOp := op
|
ctrlStatOp := op
|
||||||
|
|
||||||
err = binary.Write(hc.c, binary.BigEndian, &ctrlStatOp)
|
err = binary.Write(hc.c, binary.BigEndian, &ctrlStatOp)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// Write hmac LSB, payloadLen followed by payload
|
// Write hmac LSB, payloadLen followed by payload
|
||||||
|
@ -533,6 +534,7 @@ func (hc Conn) WritePacket(b []byte, op byte) (n int, err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
b = b[payloadLen:]
|
||||||
}
|
}
|
||||||
hc.m.Unlock()
|
hc.m.Unlock()
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"os/user"
|
"os/user"
|
||||||
"path"
|
"path"
|
||||||
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -107,19 +108,29 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *cmdSpec)
|
||||||
//os.Setenv("TERM", "vt102") // TODO: server or client option?
|
//os.Setenv("TERM", "vt102") // TODO: server or client option?
|
||||||
|
|
||||||
cmdName := "/bin/tar"
|
cmdName := "/bin/tar"
|
||||||
cmdArgs := []string{"-cz", "-f", "/dev/stdout"}
|
cmdArgs := []string{"-c", "-f", "/dev/stdout"}
|
||||||
files = strings.TrimSpace(files)
|
files = strings.TrimSpace(files)
|
||||||
// Awesome fact: tar actually can take multiple -C args, and
|
// Awesome fact: tar actually can take multiple -C args, and
|
||||||
// changes to the dest dir *as it sees each one*. This enables
|
// changes to the dest dir *as it sees each one*. This enables
|
||||||
// its use below, where clients can send scattered sets of source
|
// its use below, where clients can send scattered sets of source
|
||||||
// files and dirs to be extraced to a single dest dir server-side,
|
// files and dirs to be extracted to a single dest dir server-side,
|
||||||
// whilst preserving the subtrees of dirs on the other 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
|
// 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.
|
// packages fileInA, fileInB, and dirC at a single toplevel in the tar.
|
||||||
// The tar authors are/were real smarties :)
|
// The tar authors are/were real smarties :)
|
||||||
|
//
|
||||||
|
// This is the 'scatter/gather' logic to allow specification of
|
||||||
|
// files and dirs in different trees to be deposited in a single
|
||||||
|
// remote destDir.
|
||||||
for _, v := range strings.Split(files, " ") {
|
for _, v := range strings.Split(files, " ") {
|
||||||
|
v, _ = filepath.Abs(v)
|
||||||
dirTmp, fileTmp := path.Split(v)
|
dirTmp, fileTmp := path.Split(v)
|
||||||
cmdArgs = append(cmdArgs, "-C", dirTmp, fileTmp)
|
if dirTmp == "" {
|
||||||
|
cmdArgs = append(cmdArgs, fileTmp)
|
||||||
|
} else {
|
||||||
|
cmdArgs = append(cmdArgs, "-C", dirTmp, fileTmp)
|
||||||
|
}
|
||||||
|
|
||||||
//cmdArgs = append(cmdArgs, v)
|
//cmdArgs = append(cmdArgs, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +182,7 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *cmdSpec)
|
||||||
cmdName := "/bin/tar"
|
cmdName := "/bin/tar"
|
||||||
destPath := files
|
destPath := files
|
||||||
|
|
||||||
cmdArgs := []string{"-xz", "-C", destPath}
|
cmdArgs := []string{"-x", "-C", destPath}
|
||||||
fmt.Printf("[%v %v]\n", cmdName, cmdArgs)
|
fmt.Printf("[%v %v]\n", cmdName, cmdArgs)
|
||||||
// NOTE the lack of quotes around --xform option's sed expression.
|
// NOTE the lack of quotes around --xform option's sed expression.
|
||||||
// When args are passed in exec() format, no quoting is required
|
// When args are passed in exec() format, no quoting is required
|
||||||
|
|
|
@ -67,7 +67,7 @@ func runClientToServerCopyAs(who string, conn hkexnet.Conn, fpath string, chaffi
|
||||||
destDir = path.Join(u.HomeDir, fpath)
|
destDir = path.Join(u.HomeDir, fpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdArgs := []string{"-xz", "-C", destDir}
|
cmdArgs := []string{"-x", "-C", destDir}
|
||||||
|
|
||||||
// NOTE the lack of quotes around --xform option's sed expression.
|
// NOTE the lack of quotes around --xform option's sed expression.
|
||||||
// When args are passed in exec() format, no quoting is required
|
// When args are passed in exec() format, no quoting is required
|
||||||
|
@ -146,7 +146,7 @@ func runServerToClientCopyAs(who string, conn hkexnet.Conn, srcPath string, chaf
|
||||||
}
|
}
|
||||||
|
|
||||||
srcDir, srcBase := path.Split(srcPath)
|
srcDir, srcBase := path.Split(srcPath)
|
||||||
cmdArgs := []string{"-cz", "-C", srcDir, "-f", "-", srcBase}
|
cmdArgs := []string{"-c", "-C", srcDir, "-f", "-", srcBase}
|
||||||
|
|
||||||
c = exec.Command(cmdName, cmdArgs...)
|
c = exec.Command(cmdName, cmdArgs...)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue