60 lines
1.2 KiB
Go
60 lines
1.2 KiB
Go
|
// Package scp provides a simple interface to copying files over a
|
||
|
// go.crypto/ssh session.
|
||
|
package scp
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"os"
|
||
|
"path"
|
||
|
|
||
|
shellquote "github.com/kballard/go-shellquote"
|
||
|
|
||
|
"golang.org/x/crypto/ssh"
|
||
|
)
|
||
|
|
||
|
func Copy(size int64, mode os.FileMode, fileName string, contents io.Reader, destinationPath string, session *ssh.Session) error {
|
||
|
return copy(size, mode, fileName, contents, destinationPath, session)
|
||
|
}
|
||
|
|
||
|
func CopyPath(filePath, destinationPath string, session *ssh.Session) error {
|
||
|
f, err := os.Open(filePath)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
defer f.Close()
|
||
|
s, err := f.Stat()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
return copy(s.Size(), s.Mode().Perm(), path.Base(filePath), f, destinationPath, session)
|
||
|
}
|
||
|
|
||
|
func copy(size int64, mode os.FileMode, fileName string, contents io.Reader, destination string, session *ssh.Session) error {
|
||
|
defer session.Close()
|
||
|
w, err := session.StdinPipe()
|
||
|
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
cmd := shellquote.Join("scp", "-t", destination)
|
||
|
if err := session.Start(cmd); err != nil {
|
||
|
w.Close()
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
errors := make(chan error)
|
||
|
|
||
|
go func() {
|
||
|
errors <- session.Wait()
|
||
|
}()
|
||
|
|
||
|
fmt.Fprintf(w, "C%#o %d %s\n", mode, size, fileName)
|
||
|
io.Copy(w, contents)
|
||
|
fmt.Fprint(w, "\x00")
|
||
|
w.Close()
|
||
|
|
||
|
return <-errors
|
||
|
}
|