func (d *MemoryDriver) Rename(from_path string, to_path string) bool { if f, from_path_exists := d.Files[from_path]; from_path_exists { if _, to_path_exists := d.Files[to_path]; !to_path_exists { if _, to_path_parent_exists := d.Files[filepath.Dir(to_path)]; to_path_parent_exists { if f.File.IsDir() { delete(d.Files, from_path) d.Files[to_path] = &MemoryFile{graval.NewDirItem(filepath.Base(to_path)), nil} torename := make([]string, 0) for p, _ := range d.Files { if strings.HasPrefix(p, from_path+"/") { torename = append(torename, p) } } for _, p := range torename { sf := d.Files[p] delete(d.Files, p) np := to_path + p[len(from_path):] d.Files[np] = sf } } else { delete(d.Files, from_path) d.Files[to_path] = &MemoryFile{graval.NewFileItem(filepath.Base(to_path), f.File.Size(), f.File.ModTime()), f.Content} } return true } else { return false } } else { return false } } else { return false } }
func (d *MemoryDriver) MakeDir(path string) bool { if _, ok := d.Files[path]; ok { return false } else { d.Files[path] = &MemoryFile{graval.NewDirItem(filepath.Base(path)), nil} return true } }
// DirContents lists “directory” contents on S3 func (d *S3Driver) DirContents(path string) ([]os.FileInfo, bool) { moreObjects := true var objects []*s3.Object var resp *s3.ListObjectsOutput var err error marker := "" for moreObjects { resp, err = d.s3DirContents(path, 1000, marker) if err == nil { for _, obj := range resp.Contents { objects = append(objects, obj) } moreObjects = *resp.IsTruncated if moreObjects { last := objects[len(objects)-1] marker = *last.Key } } } prefix := pathToS3PathPrefix(path) var files []os.FileInfo var dirs []string for _, object := range objects { p := *object.Key p = strings.TrimPrefix(p, *prefix) var fi os.FileInfo if strings.Contains(p, "/") || p == "" { parts := strings.Split(p, "/") dirPart := parts[0] if dirPart != d.WorkingDirectory && dirPart != "" && dirPart != "/" && !stringInSlice(dirPart, dirs) { fi = graval.NewDirItem(dirPart) files = append(files, fi) dirs = append(dirs, dirPart) } } else { fi = graval.NewFileItem(*object.Key, *object.Size, *object.LastModified) files = append(files, fi) } } return files, true }
func main() { host := "127.0.0.1" port := 8021 username := "******" password := "******" files := map[string]*memory.MemoryFile{ "/": &memory.MemoryFile{graval.NewDirItem(""), nil}, } factory := &memory.MemoryDriverFactory{files, username, password} server := graval.NewFTPServer(&graval.FTPServerOpts{ ServerName: "Example FTP server", Factory: factory, Hostname: host, Port: port, PassiveOpts: &graval.PassiveOpts{ ListenAddress: host, NatAddress: host, PassivePorts: &graval.PassivePorts{ Low: 42000, High: 45000, }, }, }) log.Printf("Example FTP server listening on %s:%d", host, port) log.Printf("Access: ftp://%s:%s@%s:%d/", username, password, host, port) err := server.ListenAndServe() if err != nil { log.Fatal(err) } }