mirror of https://gogs.blitter.com/RLabs/xs
				
				
				
			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
					
				| 
						 | 
					@ -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 New Issue