Documentation
¶
Overview ¶
Example ¶
package main
import (
"log"
"github.com/ad3n/sftp"
"golang.org/x/crypto/ssh"
)
func main() {
var conn *ssh.Client
client, err := sftp.NewClient(conn)
if err != nil {
log.Fatal(err)
}
defer client.Close()
w := client.Walk("/home/user")
for w.Step() {
if w.Err() != nil {
continue
}
log.Println(w.Path())
}
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()
fi, err := client.Lstat("hello.txt")
if err != nil {
log.Fatal(err)
}
log.Println(fi)
}
Output:
Example (Reconnect) ¶
package main
import (
"log"
"sync"
"time"
"github.com/ad3n/sftp"
"golang.org/x/crypto/ssh"
)
type reconnectingClient struct {
addr string
config *ssh.ClientConfig
mu sync.Mutex
client *sftp.Client
done chan struct{}
}
func (rc *reconnectingClient) Client() (*sftp.Client, error) {
rc.mu.Lock()
defer rc.mu.Unlock()
if rc.client != nil {
select {
case <-rc.done:
default:
if _, err := rc.client.RealPath("."); err == nil {
return rc.client, nil
}
rc.client.Close()
}
rc.client = nil
}
conn, err := ssh.Dial("tcp", rc.addr, rc.config)
if err != nil {
return nil, err
}
client, err := sftp.NewClient(conn)
if err != nil {
conn.Close()
return nil, err
}
done := make(chan struct{})
go func() {
err := client.Wait()
conn.Close()
close(done)
log.Print("sftp: disconnected: ", err)
}()
rc.client, rc.done = client, done
return client, nil
}
func (rc *reconnectingClient) Close() error {
rc.mu.Lock()
defer rc.mu.Unlock()
if rc.client == nil {
return nil
}
err := rc.client.Close()
<-rc.done
rc.client = nil
return err
}
func main() {
var config *ssh.ClientConfig
rc := &reconnectingClient{
addr: "example.com:22",
config: config,
}
defer rc.Close()
for range time.Tick(time.Minute) {
client, err := rc.Client()
if err != nil {
log.Print(err)
continue
}
fi, err := client.Stat("/upload/ready")
if err != nil {
log.Print(err)
continue
}
log.Print(fi.Name(), " is ready")
}
}
Output:
Index ¶
- Constants
- Variables
- func Join(elem ...string) string
- func Match(pattern, name string) (matched bool, err error)
- func SetSFTPExtensions(extensions ...string) error
- func Split(p string) (dir, file string)
- type Client
- func (c *Client) Chmod(path string, mode os.FileMode) error
- func (c *Client) Chown(path string, uid, gid int) error
- func (c *Client) Chtimes(path string, atime time.Time, mtime time.Time) error
- func (c *Client) Close() error
- func (c *Client) Create(path string) (*File, error)
- func (c *Client) Getwd() (string, error)
- func (c *Client) Glob(pattern string) (matches []string, err error)
- func (c *Client) HasExtension(name string) (string, bool)
- func (c *Client) Join(elem ...string) string
- func (c *Client) Link(oldname, newname string) error
- func (c *Client) Lstat(p string) (os.FileInfo, error)
- func (c *Client) Mkdir(path string) error
- func (c *Client) MkdirAll(path string) error
- func (c *Client) Open(path string) (*File, error)
- func (c *Client) OpenFile(path string, f int) (*File, error)
- func (c *Client) PosixRename(oldname, newname string) error
- func (c *Client) ReadDir(p string) ([]os.FileInfo, error)
- func (c *Client) ReadDirContext(ctx context.Context, p string) ([]os.FileInfo, error)
- func (c *Client) ReadLink(p string) (string, error)
- func (c *Client) RealPath(path string) (string, error)
- func (c *Client) Remove(path string) error
- func (c *Client) RemoveAll(path string) error
- func (c *Client) RemoveDirectory(path string) error
- func (c *Client) Rename(oldname, newname string) error
- func (c *Client) SetExtendedData(path string, extended []StatExtended) error
- func (c *Client) Stat(p string) (os.FileInfo, error)
- func (c *Client) StatVFS(path string) (*StatVFS, error)
- func (c *Client) Symlink(oldname, newname string) error
- func (c *Client) Truncate(path string, size int64) error
- func (c *Client) Wait() error
- func (c *Client) Walk(root string) *fs.Walker
- type ClientOption
- func CopyStderrTo(wr io.Writer) ClientOption
- func ForceSingleFile() ClientOption
- func MaxConcurrentRequestsPerFile(n int) ClientOption
- func MaxPacket(size int) ClientOption
- func MaxPacketChecked(size int) ClientOption
- func MaxPacketUnchecked(size int) ClientOption
- func UseConcurrentReads(value bool) ClientOption
- func UseConcurrentWrites(value bool) ClientOption
- func UseFstat(value bool) ClientOption
- type File
- func (f *File) Chmod(mode os.FileMode) error
- func (f *File) Chown(uid, gid int) error
- func (f *File) Close() error
- func (f *File) Name() string
- func (f *File) Read(b []byte) (int, error)
- func (f *File) ReadAt(b []byte, off int64) (int, error)
- func (f *File) ReadFrom(r io.Reader) (int64, error)
- func (f *File) ReadFromWithConcurrency(r io.Reader, concurrency int) (read int64, err error)
- func (f *File) Seek(offset int64, whence int) (int64, error)
- func (f *File) SetExtendedData(path string, extended []StatExtended) error
- func (f *File) Stat() (os.FileInfo, error)
- func (f *File) Sync() error
- func (f *File) Truncate(size int64) error
- func (f *File) Write(b []byte) (int, error)
- func (f *File) WriteAt(b []byte, off int64) (written int, err error)
- func (f *File) WriteTo(w io.Writer) (written int64, err error)
- type FileAttrFlags
- type FileCmder
- type FileInfoExtendedData
- type FileInfoUidGid
- type FileLister
- type FileOpenFlags
- type FileReader
- type FileStat
- type FileWriter
- type Handlers
- type ListerAt
- type LstatFileLister
- type NameLookupFileLister
- type OpenFileWriter
- type PosixRenameFileCmder
- type ReadlinkFileLister
- type RealPathFileLister
- type Request
- type RequestServer
- type RequestServerOption
- type Server
- type ServerOption
- type StatExtended
- type StatVFS
- type StatVFSFileCmder
- type StatusError
- type TransferError
- type WriterAtReaderAt
Examples ¶
Constants ¶
View Source
const ( ErrSSHFxOk = fxerr(sshFxOk) ErrSSHFxEOF = fxerr(sshFxEOF) ErrSSHFxNoSuchFile = fxerr(sshFxNoSuchFile) ErrSSHFxPermissionDenied = fxerr(sshFxPermissionDenied) ErrSSHFxFailure = fxerr(sshFxFailure) ErrSSHFxBadMessage = fxerr(sshFxBadMessage) ErrSSHFxNoConnection = fxerr(sshFxNoConnection) ErrSSHFxConnectionLost = fxerr(sshFxConnectionLost) ErrSSHFxOpUnsupported = fxerr(sshFxOPUnsupported) ErrSshFxOk = ErrSSHFxOk ErrSshFxEof = ErrSSHFxEOF ErrSshFxNoSuchFile = ErrSSHFxNoSuchFile ErrSshFxPermissionDenied = ErrSSHFxPermissionDenied ErrSshFxFailure = ErrSSHFxFailure ErrSshFxBadMessage = ErrSSHFxBadMessage ErrSshFxNoConnection = ErrSSHFxNoConnection ErrSshFxConnectionLost = ErrSSHFxConnectionLost ErrSshFxOpUnsupported = ErrSSHFxOpUnsupported )
View Source
const EBADF = syscall.EBADF
View Source
const (
S_IFMT = uint32(sshfx.ModeType)
)
View Source
const SftpServerWorkerCount = 8
Variables ¶
View Source
var ( ErrInternalInconsistency = errors.New("internal inconsistency") InternalInconsistency = ErrInternalInconsistency )
View Source
var ErrBadPattern = path.ErrBadPattern
View Source
var MaxFilelist int64 = 100
Functions ¶
func SetSFTPExtensions ¶
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
func NewClientPipe ¶
func NewClientPipe(rd io.Reader, wr io.WriteCloser, opts ...ClientOption) (*Client, error)
Example ¶
package main
import (
"fmt"
"log"
"os"
"os/exec"
"github.com/ad3n/sftp"
)
func main() {
cmd := exec.Command("ssh", "example.com", "-s", "sftp")
cmd.Stderr = os.Stderr
wr, err := cmd.StdinPipe()
if err != nil {
log.Fatal(err)
}
rd, err := cmd.StdoutPipe()
if err != nil {
log.Fatal(err)
}
if err := cmd.Start(); err != nil {
log.Fatal(err)
}
defer cmd.Wait()
client, err := sftp.NewClientPipe(rd, wr)
if err != nil {
log.Fatal(err)
}
list, err := client.ReadDir("/")
if err != nil {
log.Fatal(err)
}
for _, item := range list {
fmt.Println(item.Name())
}
client.Close()
}
Output:
Example (Tls) ¶
package main
import (
"crypto/tls"
"fmt"
"log"
"github.com/ad3n/sftp"
)
func main() {
var clientCert tls.Certificate
conn, err := tls.Dial("tcp", "example.com:2022", &tls.Config{
Certificates: []tls.Certificate{clientCert},
})
if err != nil {
log.Fatal(err)
}
client, err := sftp.NewClientPipe(conn, conn)
if err != nil {
log.Fatal(err)
}
defer client.Close()
list, err := client.ReadDir("/")
if err != nil {
log.Fatal(err)
}
for _, item := range list {
fmt.Println(item.Name())
}
}
Output:
func (*Client) Mkdir ¶
Example (Parents) ¶
package main
import (
"fmt"
"log"
"os"
"path"
"strings"
"github.com/ad3n/sftp"
"golang.org/x/crypto/ssh"
)
func main() {
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) {
parents = "/"
}
for name := range strings.SplitSeq(dir, "/") {
if name == "" {
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)
}
}
Output:
func (*Client) PosixRename ¶
func (*Client) ReadDirContext ¶
func (*Client) RemoveDirectory ¶
func (*Client) SetExtendedData ¶
func (c *Client) SetExtendedData(path string, extended []StatExtended) error
type ClientOption ¶
func CopyStderrTo ¶
func CopyStderrTo(wr io.Writer) ClientOption
func ForceSingleFile ¶ added in v0.0.7
func ForceSingleFile() ClientOption
func MaxConcurrentRequestsPerFile ¶
func MaxConcurrentRequestsPerFile(n int) ClientOption
func MaxPacket ¶
func MaxPacket(size int) ClientOption
func MaxPacketChecked ¶
func MaxPacketChecked(size int) ClientOption
func MaxPacketUnchecked ¶
func MaxPacketUnchecked(size int) ClientOption
func UseConcurrentReads ¶
func UseConcurrentReads(value bool) ClientOption
func UseConcurrentWrites ¶
func UseConcurrentWrites(value bool) ClientOption
func UseFstat ¶
func UseFstat(value bool) ClientOption
type File ¶
type File struct {
// contains filtered or unexported fields
}
func (*File) ReadFrom ¶
Example (Bufio) ¶
package main
import (
"bufio"
"io"
"github.com/ad3n/sftp"
)
func main() {
var data_source io.Reader
var f *sftp.File
type writerOnly struct{ io.Writer }
bw := bufio.NewWriter(writerOnly{f})
bw.ReadFrom(data_source)
}
Output:
func (*File) ReadFromWithConcurrency ¶
func (*File) SetExtendedData ¶
func (f *File) SetExtendedData(path string, extended []StatExtended) error
type FileAttrFlags ¶
type FileAttrFlags struct {
Size, UidGid, Permissions, Acmodtime bool
}
type FileInfoExtendedData ¶
type FileInfoExtendedData interface {
os.FileInfo
Extended() []StatExtended
}
type FileLister ¶
type FileOpenFlags ¶
type FileOpenFlags struct {
Read, Write, Append, Creat, Trunc, Excl bool
}
type FileStat ¶
type FileStat struct {
Size uint64
Mode uint32
Mtime uint32
Atime uint32
UID uint32
GID uint32
Extended []StatExtended
}
func (*FileStat) AccessTime ¶
type Handlers ¶
type Handlers struct {
FileGet FileReader
FilePut FileWriter
FileCmd FileCmder
FileList FileLister
}
func InMemHandler ¶
func InMemHandler() Handlers
type LstatFileLister ¶
type LstatFileLister interface {
FileLister
Lstat(*Request) (ListerAt, error)
}
type NameLookupFileLister ¶
type NameLookupFileLister interface {
FileLister
LookupUserName(string) string
LookupGroupName(string) string
}
type OpenFileWriter ¶
type OpenFileWriter interface {
FileWriter
OpenFile(*Request) (WriterAtReaderAt, error)
}
type PosixRenameFileCmder ¶
type ReadlinkFileLister ¶
type ReadlinkFileLister interface {
FileLister
Readlink(string) (string, error)
}
type RealPathFileLister ¶
type RealPathFileLister interface {
FileLister
RealPath(string) (string, error)
}
type Request ¶
type Request struct {
Method string
Filepath string
Flags uint32
Attrs []byte
Target string
// contains filtered or unexported fields
}
func NewRequest ¶
func (*Request) AttrFlags ¶
func (r *Request) AttrFlags() FileAttrFlags
func (*Request) Attributes ¶
func (*Request) Pflags ¶
func (r *Request) Pflags() FileOpenFlags
type RequestServer ¶
type RequestServer struct {
Handlers Handlers
// contains filtered or unexported fields
}
func NewRequestServer ¶
func NewRequestServer(rwc io.ReadWriteCloser, h Handlers, options ...RequestServerOption) *RequestServer
func (*RequestServer) Close ¶
func (rs *RequestServer) Close() error
func (*RequestServer) Serve ¶
func (rs *RequestServer) Serve() error
type RequestServerOption ¶
type RequestServerOption func(*RequestServer)
func WithRSAllocator ¶
func WithRSAllocator() RequestServerOption
func WithRSMaxTxPacket ¶
func WithRSMaxTxPacket(size uint32) RequestServerOption
func WithStartDirectory ¶
func WithStartDirectory(startDirectory string) RequestServerOption
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
func NewServer ¶
func NewServer(rwc io.ReadWriteCloser, options ...ServerOption) (*Server, error)
Example ¶
package main
import (
"crypto/tls"
"crypto/x509"
"io"
"log"
"github.com/ad3n/sftp"
)
func main() {
var serverCert tls.Certificate
var clientCAs *x509.CertPool
listener, err := tls.Listen("tcp", ":2022", &tls.Config{
Certificates: []tls.Certificate{serverCert},
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: clientCAs,
})
if err != nil {
log.Fatal(err)
}
for {
conn, err := listener.Accept()
if err != nil {
log.Fatal(err)
}
go func() {
server, err := sftp.NewServer(conn)
if err != nil {
log.Print(err)
conn.Close()
return
}
if err := server.Serve(); err != nil && err != io.EOF {
log.Print("sftp server completed with error: ", err)
}
conn.Close()
}()
}
}
Output:
type ServerOption ¶
func ReadOnly ¶
func ReadOnly() ServerOption
func WindowsRootEnumeratesDrives ¶
func WindowsRootEnumeratesDrives() ServerOption
func WithAllocator ¶
func WithAllocator() ServerOption
func WithDebug ¶
func WithDebug(w io.Writer) ServerOption
func WithMaxTxPacket ¶
func WithMaxTxPacket(size uint32) ServerOption
func WithServerWorkingDirectory ¶
func WithServerWorkingDirectory(workDir string) ServerOption
type StatExtended ¶
type StatVFS ¶
type StatVFS struct {
ID uint32
Bsize uint64
Frsize uint64
Blocks uint64
Bfree uint64
Bavail uint64
Files uint64
Ffree uint64
Favail uint64
Fsid uint64
Flag uint64
Namemax uint64
}
func (*StatVFS) MarshalBinary ¶
func (*StatVFS) TotalSpace ¶
type StatVFSFileCmder ¶
type StatusError ¶
type StatusError struct {
Code uint32
// contains filtered or unexported fields
}
func (*StatusError) Error ¶
func (s *StatusError) Error() string
func (*StatusError) FxCode ¶
func (s *StatusError) FxCode() fxerr
type TransferError ¶
type TransferError interface {
TransferError(err error)
}
Source Files
¶
- allocator.go
- attrs.go
- attrs_unix.go
- client.go
- conn.go
- errno_posix.go
- ls_formatting.go
- ls_unix.go
- match.go
- packet-manager.go
- packet-typing.go
- packet.go
- pool.go
- release.go
- request-attrs.go
- request-errors.go
- request-example.go
- request-interfaces.go
- request-server.go
- request-unix.go
- request.go
- server.go
- server_posix.go
- server_statvfs_impl.go
- server_statvfs_linux.go
- server_unix.go
- sftp.go
- stat.go
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
buffered-read-benchmark
command
|
|
|
buffered-write-benchmark
command
|
|
|
go-sftp-server
command
|
|
|
request-server
command
|
|
|
streaming-read-benchmark
command
|
|
|
streaming-write-benchmark
command
|
|
|
internal
|
|
Click to show internal directories.
Click to hide internal directories.