diff options
Diffstat (limited to 'vendor/github.com/pkg/sftp/request-example.go')
-rw-r--r-- | vendor/github.com/pkg/sftp/request-example.go | 261 |
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 -} |