mirror of https://gogs.blitter.com/RLabs/xs
Steps toward getting remote cp(tar) status back to client
This commit is contained in:
parent
963d1c8eb2
commit
a6979298fd
|
@ -437,9 +437,9 @@ func (hc Conn) Read(b []byte) (n int, err error) {
|
||||||
} else if ctrlStatOp == CSOExitStatus {
|
} else if ctrlStatOp == CSOExitStatus {
|
||||||
if len(payloadBytes) > 0 {
|
if len(payloadBytes) > 0 {
|
||||||
*hc.closeStat = uint8(payloadBytes[0])
|
*hc.closeStat = uint8(payloadBytes[0])
|
||||||
// If remote end is closing (255), reply we're closing ours
|
// If remote end is closing with an error, reply we're closing ours
|
||||||
if payloadBytes[0] == 255 {
|
if payloadBytes[0] != 0 {
|
||||||
hc.SetStatus(255)
|
hc.SetStatus(payloadBytes[0])
|
||||||
hc.Close()
|
hc.Close()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -142,11 +143,8 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *cmdSpec)
|
||||||
c.Dir, _ = os.Getwd()
|
c.Dir, _ = os.Getwd()
|
||||||
fmt.Println("[wd:", c.Dir, "]")
|
fmt.Println("[wd:", c.Dir, "]")
|
||||||
c.Stdout = conn
|
c.Stdout = conn
|
||||||
// Stderr sinkholing is important. Any extraneous output to tarpipe
|
stdErrBuffer := new(bytes.Buffer)
|
||||||
// messes up remote side as it's expecting pure tar data.
|
c.Stderr = stdErrBuffer
|
||||||
// (For example, if user specifies abs paths, tar outputs
|
|
||||||
// "Removing leading '/' from path names")
|
|
||||||
c.Stderr = nil
|
|
||||||
|
|
||||||
// Start the command (no pty)
|
// Start the command (no pty)
|
||||||
err = c.Start() // returns immediately
|
err = c.Start() // returns immediately
|
||||||
|
@ -165,12 +163,13 @@ func doCopyMode(conn *hkexnet.Conn, remoteDest bool, files string, rec *cmdSpec)
|
||||||
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
||||||
exitStatus = status.ExitStatus()
|
exitStatus = status.ExitStatus()
|
||||||
log.Printf("Exit Status: %d", exitStatus)
|
log.Printf("Exit Status: %d", exitStatus)
|
||||||
|
fmt.Print(stdErrBuffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//fmt.Println("*** client->server cp finished ***")
|
//fmt.Println("*** client->server cp finished ***")
|
||||||
// Signal other end transfer is complete
|
// Signal other end transfer is complete
|
||||||
conn.WritePacket([]byte{byte(255)}, hkexnet.CSOExitStatus)
|
conn.WritePacket([]byte{byte(rec.status)}, hkexnet.CSOExitStatus)
|
||||||
_, _ = conn.Read(nil /*ackByte*/)
|
_, _ = conn.Read(nil /*ackByte*/)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -157,11 +158,14 @@ func runServerToClientCopyAs(who string, conn hkexnet.Conn, srcPath string, chaf
|
||||||
c.SysProcAttr = &syscall.SysProcAttr{}
|
c.SysProcAttr = &syscall.SysProcAttr{}
|
||||||
c.SysProcAttr.Credential = &syscall.Credential{Uid: uid, Gid: gid}
|
c.SysProcAttr.Credential = &syscall.Credential{Uid: uid, Gid: gid}
|
||||||
c.Stdout = conn
|
c.Stdout = conn
|
||||||
// Stderr sinkholing is important. Any extraneous output to tarpipe
|
// Stderr sinkholing (or buffering to something other than stdout)
|
||||||
// messes up remote side as it's expecting pure tar data.
|
// is important. Any extraneous output to tarpipe messes up remote
|
||||||
|
// side as it's expecting pure tar data.
|
||||||
// (For example, if user specifies abs paths, tar outputs
|
// (For example, if user specifies abs paths, tar outputs
|
||||||
// "Removing leading '/' from path names")
|
// "Removing leading '/' from path names")
|
||||||
c.Stderr = nil
|
stdErrBuffer := new(bytes.Buffer)
|
||||||
|
c.Stderr = stdErrBuffer
|
||||||
|
//c.Stderr = nil
|
||||||
|
|
||||||
if chaffing {
|
if chaffing {
|
||||||
conn.EnableChaff()
|
conn.EnableChaff()
|
||||||
|
@ -189,6 +193,11 @@ func runServerToClientCopyAs(who string, conn hkexnet.Conn, srcPath string, chaf
|
||||||
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
||||||
exitStatus = status.ExitStatus()
|
exitStatus = status.ExitStatus()
|
||||||
log.Printf("Exit Status: %d", exitStatus)
|
log.Printf("Exit Status: %d", exitStatus)
|
||||||
|
// TODO: send stdErrBuffer to client via specific packet
|
||||||
|
// type so it can inform user
|
||||||
|
if len(stdErrBuffer.Bytes()) > 0 {
|
||||||
|
fmt.Print("TODO: (stderrBuffer to client):", stdErrBuffer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,6 +226,7 @@ func runShellAs(who string, cmd string, interactive bool, conn hkexnet.Conn, cha
|
||||||
// Investigate -- rlm 2018-01-26)
|
// Investigate -- rlm 2018-01-26)
|
||||||
os.Clearenv()
|
os.Clearenv()
|
||||||
os.Setenv("HOME", u.HomeDir)
|
os.Setenv("HOME", u.HomeDir)
|
||||||
|
//os.Setenv("SHELL", "/bin/bash")
|
||||||
os.Setenv("TERM", "vt102") // TODO: server or client option?
|
os.Setenv("TERM", "vt102") // TODO: server or client option?
|
||||||
|
|
||||||
var c *exec.Cmd
|
var c *exec.Cmd
|
||||||
|
@ -262,8 +272,9 @@ func runShellAs(who string, cmd string, interactive bool, conn hkexnet.Conn, cha
|
||||||
_, e := io.Copy(ptmx, conn)
|
_, e := io.Copy(ptmx, conn)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
log.Println("** stdin->pty ended **:", e.Error())
|
log.Println("** stdin->pty ended **:", e.Error())
|
||||||
|
} else {
|
||||||
|
log.Println("*** stdin->pty goroutine done ***")
|
||||||
}
|
}
|
||||||
fmt.Println("*** stdin->pty goroutine done ***")
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if chaffing {
|
if chaffing {
|
||||||
|
@ -284,10 +295,11 @@ func runShellAs(who string, cmd string, interactive bool, conn hkexnet.Conn, cha
|
||||||
_, e := io.Copy(conn, ptmx)
|
_, e := io.Copy(conn, ptmx)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
log.Println("** pty->stdout ended **:", e.Error())
|
log.Println("** pty->stdout ended **:", e.Error())
|
||||||
}
|
} else {
|
||||||
// The above io.Copy() will exit when the command attached
|
// The above io.Copy() will exit when the command attached
|
||||||
// to the pty exits
|
// to the pty exits
|
||||||
fmt.Println("*** pty->stdout goroutine done ***")
|
log.Println("*** pty->stdout goroutine done ***")
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err := c.Wait(); err != nil {
|
if err := c.Wait(); err != nil {
|
||||||
|
@ -486,8 +498,6 @@ func main() {
|
||||||
} else if rec.op[0] == 'D' {
|
} else if rec.op[0] == 'D' {
|
||||||
// File copy (destination) operation - client copy to server
|
// File copy (destination) operation - client copy to server
|
||||||
log.Printf("[Client->Server copy]\n")
|
log.Printf("[Client->Server copy]\n")
|
||||||
// TODO: call function with hc, rec.cmd, chaffEnabled etc.
|
|
||||||
// func hooks tar cmd right-half of pipe to hc Reader
|
|
||||||
addr := hc.RemoteAddr()
|
addr := hc.RemoteAddr()
|
||||||
hname := strings.Split(addr.String(), ":")[0]
|
hname := strings.Split(addr.String(), ":")[0]
|
||||||
log.Printf("[Running copy for [%s@%s]]\n", rec.who, hname)
|
log.Printf("[Running copy for [%s@%s]]\n", rec.who, hname)
|
||||||
|
@ -499,13 +509,11 @@ func main() {
|
||||||
log.Printf("[Error spawning cp for %s@%s]\n", rec.who, hname)
|
log.Printf("[Error spawning cp for %s@%s]\n", rec.who, hname)
|
||||||
} else {
|
} else {
|
||||||
log.Printf("[Command completed for %s@%s, status %d]\n", rec.who, hname, cmdStatus)
|
log.Printf("[Command completed for %s@%s, status %d]\n", rec.who, hname, cmdStatus)
|
||||||
hc.SetStatus(uint8(cmdStatus))
|
|
||||||
}
|
}
|
||||||
|
hc.SetStatus(uint8(cmdStatus))
|
||||||
} else if rec.op[0] == 'S' {
|
} else if rec.op[0] == 'S' {
|
||||||
// File copy (src) operation - server copy to client
|
// File copy (src) operation - server copy to client
|
||||||
log.Printf("[Server->Client copy]\n")
|
log.Printf("[Server->Client copy]\n")
|
||||||
// TODO: call function to copy rec.cmd (file list) to
|
|
||||||
// tar cmd left-half of pipeline to hc.Writer ?
|
|
||||||
addr := hc.RemoteAddr()
|
addr := hc.RemoteAddr()
|
||||||
hname := strings.Split(addr.String(), ":")[0]
|
hname := strings.Split(addr.String(), ":")[0]
|
||||||
log.Printf("[Running copy for [%s@%s]]\n", rec.who, hname)
|
log.Printf("[Running copy for [%s@%s]]\n", rec.who, hname)
|
||||||
|
@ -517,10 +525,10 @@ func main() {
|
||||||
log.Printf("[Error spawning cp for %s@%s]\n", rec.who, hname)
|
log.Printf("[Error spawning cp for %s@%s]\n", rec.who, hname)
|
||||||
} else {
|
} else {
|
||||||
log.Printf("[Command completed for %s@%s, status %d]\n", rec.who, hname, cmdStatus)
|
log.Printf("[Command completed for %s@%s, status %d]\n", rec.who, hname, cmdStatus)
|
||||||
hc.SetStatus(uint8(cmdStatus))
|
|
||||||
}
|
}
|
||||||
|
hc.SetStatus(uint8(cmdStatus))
|
||||||
// Signal other end transfer is complete
|
// Signal other end transfer is complete
|
||||||
hc.WritePacket([]byte{byte(255)}, hkexnet.CSOExitStatus)
|
hc.WritePacket([]byte{byte(cmdStatus)}, hkexnet.CSOExitStatus)
|
||||||
//fmt.Println("Waiting for EOF from other end.")
|
//fmt.Println("Waiting for EOF from other end.")
|
||||||
//ackByte := make([]byte, 1, 1)
|
//ackByte := make([]byte, 1, 1)
|
||||||
_, _ = hc.Read(nil /*ackByte*/)
|
_, _ = hc.Read(nil /*ackByte*/)
|
||||||
|
|
Loading…
Reference in New Issue