1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
package sftp_test
import (
"bufio"
"fmt"
"io"
"log"
"os"
"os/exec"
"path"
"strings"
"github.com/pkg/sftp"
"golang.org/x/crypto/ssh"
)
func Example() {
var conn *ssh.Client
// open an SFTP session over an existing ssh connection.
client, err := sftp.NewClient(conn)
if err != nil {
log.Fatal(err)
}
defer client.Close()
// walk a directory
w := client.Walk("/home/user")
for w.Step() {
if w.Err() != nil {
continue
}
log.Println(w.Path())
}
// leave your mark
f, err := client.Create("hello.txt")
if err != nil {
log.Fatal(err)
}
if _, err := f.Write([]byte("Hello world!")); err != nil {
log.Fatal(err)
}
f.Close()
// check it's there
fi, err := client.Lstat("hello.txt")
if err != nil {
log.Fatal(err)
}
log.Println(fi)
}
func ExampleNewClientPipe() {
// Connect to a remote host and request the sftp subsystem via the 'ssh'
// command. This assumes that passwordless login is correctly configured.
cmd := exec.Command("ssh", "example.com", "-s", "sftp")
// send errors from ssh to stderr
cmd.Stderr = os.Stderr
// get stdin and stdout
wr, err := cmd.StdinPipe()
if err != nil {
log.Fatal(err)
}
rd, err := cmd.StdoutPipe()
if err != nil {
log.Fatal(err)
}
// start the process
if err := cmd.Start(); err != nil {
log.Fatal(err)
}
defer cmd.Wait()
// open the SFTP session
client, err := sftp.NewClientPipe(rd, wr)
if err != nil {
log.Fatal(err)
}
// read a directory
list, err := client.ReadDir("/")
if err != nil {
log.Fatal(err)
}
// print contents
for _, item := range list {
fmt.Println(item.Name())
}
// close the connection
client.Close()
}
func ExampleClient_Mkdir_parents() {
// Example of mimicing 'mkdir --parents'; I.E. recursively create
// directoryies and don't error if any directories already exists.
var conn *ssh.Client
client, err := sftp.NewClient(conn)
if err != nil {
log.Fatal(err)
}
defer client.Close()
sshFxFailure := uint32(4)
mkdirParents := func(client *sftp.Client, dir string) (err error) {
var parents string
if path.IsAbs(dir) {
// Otherwise, an absolute path given below would be turned in to a relative one
// by splitting on "/"
parents = "/"
}
for _, name := range strings.Split(dir, "/") {
if name == "" {
// Paths with double-/ in them should just move along
// this will also catch the case of the first character being a "/", i.e. an absolute path
continue
}
parents = path.Join(parents, name)
err = client.Mkdir(parents)
if status, ok := err.(*sftp.StatusError); ok {
if status.Code == sshFxFailure {
var fi os.FileInfo
fi, err = client.Stat(parents)
if err == nil {
if !fi.IsDir() {
return fmt.Errorf("file exists: %s", parents)
}
}
}
}
if err != nil {
break
}
}
return err
}
err = mkdirParents(client, "/tmp/foo/bar")
if err != nil {
log.Fatal(err)
}
}
func ExampleFile_ReadFrom_bufio() {
// Using Bufio to buffer writes going to an sftp.File won't buffer as it
// skips buffering if the underlying writer support ReadFrom. The
// workaround is to wrap your writer in a struct that only implements
// io.Writer.
//
// For background see github.com/pkg/sftp/issues/125
var data_source io.Reader
var f *sftp.File
type writerOnly struct{ io.Writer }
bw := bufio.NewWriter(writerOnly{f}) // no ReadFrom()
bw.ReadFrom(data_source)
}
|