func (d *directory) Create(ctx context.Context, request *fuse.CreateRequest, response *fuse.CreateResponse) (result fs.Node, _ fs.Handle, retErr error) { defer func() { if retErr == nil { protolion.Debug(&DirectoryCreate{&d.Node, getNode(result), errorToString(retErr)}) } else { protolion.Error(&DirectoryCreate{&d.Node, getNode(result), errorToString(retErr)}) } }() if d.File.Commit.ID == "" { return nil, 0, fuse.EPERM } directory := d.copy() directory.File.Path = path.Join(directory.File.Path, request.Name) localResult := &file{ directory: *directory, size: 0, } if err := localResult.touch(); err != nil { return nil, 0, err } response.Flags |= fuse.OpenDirectIO | fuse.OpenNonSeekable handle := localResult.newHandle(0) return localResult, handle, nil }
func (d *Dir) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (fs.Node, fs.Handle, error) { glog.Infof("Entered Create Dir\n") if req.Flags.IsReadOnly() { glog.Info("Create: File requested is read only.\n") } if req.Flags.IsReadWrite() { glog.Info("Create: File requested is read write.\n") } if req.Flags.IsWriteOnly() { glog.Info("Create: File requested is write only.\n") } if runtime.GOOS == "darwin" { resp.Flags |= fuse.OpenDirectIO } if d.artist == "drop" { if len(d.album) > 0 { glog.Info("Subdirectories are not allowed in drop folder.") return nil, nil, fuse.EIO } rootPoint := d.mPoint if rootPoint[len(rootPoint)-1] != '/' { rootPoint = rootPoint + "/" } name := req.Name path := rootPoint + "drop/" extension := filepath.Ext(name) if extension != ".mp3" { glog.Info("Only mp3 files are allowed.") return nil, nil, fuse.EIO } // Check if the drop directory exists src, err := os.Stat(path) if err != nil || !src.IsDir() { err = os.MkdirAll(path, 0777) if err != nil { glog.Infof("Cannot create dir: %s\n", err) return nil, nil, err } } fi, err := os.Create(path + name) if err != nil { glog.Infof("Cannot create file: %s\n", err) return nil, nil, err } keyName := name[:len(name)-len(extension)] f := &File{ artist: d.artist, album: d.album, song: keyName, name: name, mPoint: d.mPoint, } if fi != nil { glog.Infof("Returning file handle for: %s.\n", fi.Name()) } return f, &FileHandle{r: fi, f: f}, nil } if d.artist == "playlists" { if len(d.album) < 1 { glog.Info("Files are not allowed outside playlists.") return nil, nil, fuse.EIO } rootPoint := d.mPoint if rootPoint[len(rootPoint)-1] != '/' { rootPoint = rootPoint + "/" } name := req.Name path := rootPoint + "playlists/" + d.album extension := filepath.Ext(name) if extension != ".mp3" { glog.Info("Only mp3 files are allowed.") return nil, nil, fuse.EIO } // Check if the playlist drop directory exists src, err := os.Stat(path) if err != nil || !src.IsDir() { err = os.MkdirAll(path, 0777) if err != nil { glog.Infof("Cannot create dir: %s\n", err) return nil, nil, err } } fi, err := os.Create(path + "/" + name) if err != nil { glog.Infof("Cannot create file: %s\n", err) return nil, nil, err } keyName := name[:len(name)-len(extension)] f := &File{ artist: d.artist, album: d.album, song: keyName, name: name, mPoint: d.mPoint, } if fi != nil { glog.Infof("Returning file handle for: %s.\n", fi.Name()) } return f, &FileHandle{r: fi, f: f}, nil } if len(d.artist) < 1 || len(d.album) < 1 { return nil, nil, fuse.EPERM } nameRaw := req.Name if nameRaw[0] == '.' { glog.Info("Cannot create files starting with dot.") return nil, nil, fuse.EPERM } rootPoint := d.mPoint if rootPoint[len(rootPoint)-1] != '/' { rootPoint = rootPoint + "/" } path := rootPoint + d.artist + "/" + d.album + "/" name, err := store.CreateSong(d.artist, d.album, nameRaw, path) if err != nil { glog.Info("Error creating song.") return nil, nil, fuse.EPERM } err = os.MkdirAll(path, 0777) if err != nil { glog.Info("Cannot create folder.") return nil, nil, err } fi, err := os.Create(path + name) if err != nil { glog.Infof("Cannot create file: %s\n", err) return nil, nil, err } extension := filepath.Ext(name) keyName := name[:len(name)-len(extension)] f := &File{ artist: d.artist, album: d.album, song: keyName, name: name, mPoint: d.mPoint, } if fi != nil { glog.Infof("Returning file handle for: %s.\n", fi.Name()) } return f, &FileHandle{r: fi, f: f}, nil }
//creates new file only func (d dir) Create( request *fuse.CreateRequest, response *fuse.CreateResponse, intr fs.Intr, ) (fs.Node, fs.Handle, fuse.Error) { log.Printf("Request:\n %+v\nObject: %+v", request, d) select { case <-intr: return nil, nil, fuse.EINTR default: } // O_RDONLY int = os.O_RDONLY // open the file read-only. // O_WRONLY int = os.O_WRONLY // open the file write-only. // O_RDWR int = os.O_RDWR // open the file read-write. // O_APPEND int = os.O_APPEND // append data to the file when writing. // O_CREATE int = os.O_CREAT // create a new file if none exists. // O_EXCL int = os.O_EXCL // used with O_CREATE, file must not exist // O_SYNC int = os.O_SYNC // open for synchronous I/O. // O_TRUNC int = os.O_TRUNC // if possible, truncate file when opened. node := file{ contentHash: objects.Blob{}.Hash(), permission: os.FileMode(0777), //request.Mode, parent: &d, name: request.Name, inode: generateInode(d.inode, request.Name), size: 0, flags: request.Flags & 7, } handle := openFileHandle{ buffer: []byte{}, parent: &d, file: &node, name: request.Name, inode: node.inode, publish: true, handleNum: 1, } switch { default: log.Printf("unexpected requests.flag error:%+v", request.Flags) return nil, nil, fuse.ENOSYS // case O_RDONLY, O_RDWR, O_APPEND, O_SYNC: //OPEN FILE if it exists // if err != nil { // return nil, fuse.ENOENT // } case os.O_EXCL&int(request.Flags) == os.O_EXCL: _, LookupErr := d.Lookup(request.Name, intr) if LookupErr == nil { return nil, nil, fuse.EEXIST } fallthrough //-- file doesn't exist case os.O_CREATE&int(request.Flags) == os.O_CREATE: d.openHandles[handle.name] = &handle response.Flags = 1 << 2 return &node, &handle, nil // case O_WRONLY, O_APPEND: //OPEN AN EMPTY FILE // if err == nil { // return nil, fuse.EEXIST // } //case O_TRUNC: //return ENOSYS } //return node, handle, nil }