Files
zrepl_patched/zync/transport/sshdirect/serve.go
T
Christian Schwarz bd30afaaf9 experiment: zync: an rsync-like tool for ZFS datasets (re-uses zrepl abstractions)
Local sync and sync over SSH seems to work.
The sshdirect transport might be interesting / re-usable for zrepl as well, although we'd still need some kind of locking in that case.
2021-01-14 01:33:24 +01:00

92 lines
1.7 KiB
Go

package sshdirect
import (
"bytes"
"io"
"log"
"net"
"os"
"time"
"github.com/hashicorp/yamux"
)
type ServeConn struct {
stdin, stdout *os.File
}
var _ net.Conn = (*ServeConn)(nil)
func ServeStdin() (net.Listener, error) {
conn := &ServeConn{
stdin: os.Stdin,
stdout: os.Stdout,
}
var buf bytes.Buffer
buf.Write(banner_msg)
if _, err := io.Copy(conn, &buf); err != nil {
log.Printf("error sending confirm message: %s", err)
conn.Close()
return nil, err
}
buf.Reset()
if _, err := io.CopyN(&buf, conn, int64(len(begin_msg))); err != nil {
log.Printf("error reading begin message: %s", err)
conn.Close()
return nil, err
}
return yamux.Server(conn, nil)
}
func (c *ServeConn) Read(p []byte) (int, error) {
return c.stdin.Read(p)
}
func (c *ServeConn) Write(p []byte) (int, error) {
return c.stdout.Write(p)
}
func (f *ServeConn) Close() (err error) {
e1 := f.stdin.Close()
e2 := f.stdout.Close()
// FIXME merge errors
if e1 != nil {
return e1
}
return e2
}
func (f *ServeConn) SetReadDeadline(t time.Time) error {
return f.stdin.SetReadDeadline(t)
}
func (f *ServeConn) SetWriteDeadline(t time.Time) error {
return f.stdout.SetReadDeadline(t)
}
func (f *ServeConn) SetDeadline(t time.Time) error {
// try both...
werr := f.SetWriteDeadline(t)
rerr := f.SetReadDeadline(t)
if werr != nil {
return werr
}
if rerr != nil {
return rerr
}
return nil
}
type serveAddr struct{}
const GoNetwork string = "sshdirect"
func (serveAddr) Network() string { return GoNetwork }
func (serveAddr) String() string { return "???" }
func (f *ServeConn) LocalAddr() net.Addr { return serveAddr{} }
func (f *ServeConn) RemoteAddr() net.Addr { return serveAddr{} }