golang-github-tmc-scp/0000755000175000017500000000000013261573024013634 5ustar aronarongolang-github-tmc-scp/scp_example_test.go0000644000175000017500000000235213261573003017521 0ustar aronaronpackage scp_test import ( "fmt" "io/ioutil" "log" "net" "os" "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" "github.com/tmc/scp" ) func getAgent() (agent.Agent, error) { agentConn, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")) return agent.NewClient(agentConn), err } func ExampleCopyPath() { f, _ := ioutil.TempFile("", "") fmt.Fprintln(f, "hello world") f.Close() defer os.Remove(f.Name()) defer os.Remove(f.Name() + "-copy") agent, err := getAgent() if err != nil { log.Fatalln("Failed to connect to SSH_AUTH_SOCK:", err) } client, err := ssh.Dial("tcp", "127.0.0.1:22", &ssh.ClientConfig{ User: os.Getenv("USER"), Auth: []ssh.AuthMethod{ ssh.PublicKeysCallback(agent.Signers), }, HostKeyCallback: ssh.InsecureIgnoreHostKey(), // FIXME: please be more secure in checking host keys }) if err != nil { log.Fatalln("Failed to dial:", err) } session, err := client.NewSession() if err != nil { log.Fatalln("Failed to create session: " + err.Error()) } dest := f.Name() + "-copy" err = scp.CopyPath(f.Name(), dest, session) if _, err := os.Stat(dest); os.IsNotExist(err) { fmt.Printf("no such file or directory: %s", dest) } else { fmt.Println("success") } // output: // success } golang-github-tmc-scp/LICENSE0000644000175000017500000000136513261573003014643 0ustar aronaronCopyright (c) 2014, Travis Cline Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. golang-github-tmc-scp/README.md0000644000175000017500000000060113261573003015105 0ustar aronaron# scp import "github.com/tmc/scp" Package scp provides a simple interface to copying files over a go.crypto/ssh session. ## func Copy ``` go func Copy(size int64, mode os.FileMode, fileName string, contents io.Reader, destinationPath string, session *ssh.Session) error ``` ## func CopyPath ``` go func CopyPath(filePath, destinationPath string, session *ssh.Session) error ``` golang-github-tmc-scp/scp.go0000644000175000017500000000237213261573003014751 0ustar aronaron// 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 }