summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/pkg/sftp/request-example.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/pkg/sftp/request-example.go')
-rw-r--r--vendor/github.com/pkg/sftp/request-example.go261
1 files changed, 0 insertions, 261 deletions
diff --git a/vendor/github.com/pkg/sftp/request-example.go b/vendor/github.com/pkg/sftp/request-example.go
deleted file mode 100644
index 96191e0d..00000000
--- a/vendor/github.com/pkg/sftp/request-example.go
+++ /dev/null
@@ -1,261 +0,0 @@
-package sftp
-
-// This serves as an example of how to implement the request server handler as
-// well as a dummy backend for testing. It implements an in-memory backend that
-// works as a very simple filesystem with simple flat key-value lookup system.
-
-import (
- "bytes"
- "fmt"
- "io"
- "os"
- "path/filepath"
- "sort"
- "sync"
- "time"
-)
-
-// InMemHandler returns a Hanlders object with the test handlers
-func InMemHandler() Handlers {
- root := &root{
- files: make(map[string]*memFile),
- }
- root.memFile = newMemFile("/", true)
- return Handlers{root, root, root, root}
-}
-
-// Handlers
-func (fs *root) Fileread(r *Request) (io.ReaderAt, error) {
- if fs.mockErr != nil {
- return nil, fs.mockErr
- }
- fs.filesLock.Lock()
- defer fs.filesLock.Unlock()
- file, err := fs.fetch(r.Filepath)
- if err != nil {
- return nil, err
- }
- if file.symlink != "" {
- file, err = fs.fetch(file.symlink)
- if err != nil {
- return nil, err
- }
- }
- return file.ReaderAt()
-}
-
-func (fs *root) Filewrite(r *Request) (io.WriterAt, error) {
- if fs.mockErr != nil {
- return nil, fs.mockErr
- }
- fs.filesLock.Lock()
- defer fs.filesLock.Unlock()
- file, err := fs.fetch(r.Filepath)
- if err == os.ErrNotExist {
- dir, err := fs.fetch(filepath.Dir(r.Filepath))
- if err != nil {
- return nil, err
- }
- if !dir.isdir {
- return nil, os.ErrInvalid
- }
- file = newMemFile(r.Filepath, false)
- fs.files[r.Filepath] = file
- }
- return file.WriterAt()
-}
-
-func (fs *root) Filecmd(r *Request) error {
- if fs.mockErr != nil {
- return fs.mockErr
- }
- fs.filesLock.Lock()
- defer fs.filesLock.Unlock()
- switch r.Method {
- case "Setstat":
- return nil
- case "Rename":
- file, err := fs.fetch(r.Filepath)
- if err != nil {
- return err
- }
- if _, ok := fs.files[r.Target]; ok {
- return &os.LinkError{Op: "rename", Old: r.Filepath, New: r.Target,
- Err: fmt.Errorf("dest file exists")}
- }
- fs.files[r.Target] = file
- delete(fs.files, r.Filepath)
- case "Rmdir", "Remove":
- _, err := fs.fetch(filepath.Dir(r.Filepath))
- if err != nil {
- return err
- }
- delete(fs.files, r.Filepath)
- case "Mkdir":
- _, err := fs.fetch(filepath.Dir(r.Filepath))
- if err != nil {
- return err
- }
- fs.files[r.Filepath] = newMemFile(r.Filepath, true)
- case "Symlink":
- _, err := fs.fetch(r.Filepath)
- if err != nil {
- return err
- }
- link := newMemFile(r.Target, false)
- link.symlink = r.Filepath
- fs.files[r.Target] = link
- }
- return nil
-}
-
-type listerat []os.FileInfo
-
-// Modeled after strings.Reader's ReadAt() implementation
-func (f listerat) ListAt(ls []os.FileInfo, offset int64) (int, error) {
- var n int
- if offset >= int64(len(f)) {
- return 0, io.EOF
- }
- n = copy(ls, f[offset:])
- if n < len(ls) {
- return n, io.EOF
- }
- return n, nil
-}
-
-func (fs *root) Filelist(r *Request) (ListerAt, error) {
- if fs.mockErr != nil {
- return nil, fs.mockErr
- }
- fs.filesLock.Lock()
- defer fs.filesLock.Unlock()
-
- switch r.Method {
- case "List":
- ordered_names := []string{}
- for fn, _ := range fs.files {
- if filepath.Dir(fn) == r.Filepath {
- ordered_names = append(ordered_names, fn)
- }
- }
- sort.Strings(ordered_names)
- list := make([]os.FileInfo, len(ordered_names))
- for i, fn := range ordered_names {
- list[i] = fs.files[fn]
- }
- return listerat(list), nil
- case "Stat":
- file, err := fs.fetch(r.Filepath)
- if err != nil {
- return nil, err
- }
- return listerat([]os.FileInfo{file}), nil
- case "Readlink":
- file, err := fs.fetch(r.Filepath)
- if err != nil {
- return nil, err
- }
- if file.symlink != "" {
- file, err = fs.fetch(file.symlink)
- if err != nil {
- return nil, err
- }
- }
- return listerat([]os.FileInfo{file}), nil
- }
- return nil, nil
-}
-
-// In memory file-system-y thing that the Hanlders live on
-type root struct {
- *memFile
- files map[string]*memFile
- filesLock sync.Mutex
- mockErr error
-}
-
-// Set a mocked error that the next handler call will return.
-// Set to nil to reset for no error.
-func (fs *root) returnErr(err error) {
- fs.mockErr = err
-}
-
-func (fs *root) fetch(path string) (*memFile, error) {
- if path == "/" {
- return fs.memFile, nil
- }
- if file, ok := fs.files[path]; ok {
- return file, nil
- }
- return nil, os.ErrNotExist
-}
-
-// Implements os.FileInfo, Reader and Writer interfaces.
-// These are the 3 interfaces necessary for the Handlers.
-type memFile struct {
- name string
- modtime time.Time
- symlink string
- isdir bool
- content []byte
- contentLock sync.RWMutex
-}
-
-// factory to make sure modtime is set
-func newMemFile(name string, isdir bool) *memFile {
- return &memFile{
- name: name,
- modtime: time.Now(),
- isdir: isdir,
- }
-}
-
-// Have memFile fulfill os.FileInfo interface
-func (f *memFile) Name() string { return filepath.Base(f.name) }
-func (f *memFile) Size() int64 { return int64(len(f.content)) }
-func (f *memFile) Mode() os.FileMode {
- ret := os.FileMode(0644)
- if f.isdir {
- ret = os.FileMode(0755) | os.ModeDir
- }
- if f.symlink != "" {
- ret = os.FileMode(0777) | os.ModeSymlink
- }
- return ret
-}
-func (f *memFile) ModTime() time.Time { return f.modtime }
-func (f *memFile) IsDir() bool { return f.isdir }
-func (f *memFile) Sys() interface{} {
- return fakeFileInfoSys()
-}
-
-// Read/Write
-func (f *memFile) ReaderAt() (io.ReaderAt, error) {
- if f.isdir {
- return nil, os.ErrInvalid
- }
- return bytes.NewReader(f.content), nil
-}
-
-func (f *memFile) WriterAt() (io.WriterAt, error) {
- if f.isdir {
- return nil, os.ErrInvalid
- }
- return f, nil
-}
-func (f *memFile) WriteAt(p []byte, off int64) (int, error) {
- // fmt.Println(string(p), off)
- // mimic write delays, should be optional
- time.Sleep(time.Microsecond * time.Duration(len(p)))
- f.contentLock.Lock()
- defer f.contentLock.Unlock()
- plen := len(p) + int(off)
- if plen >= len(f.content) {
- nc := make([]byte, plen)
- copy(nc, f.content)
- f.content = nc
- }
- copy(f.content[off:], p)
- return len(p), nil
-}