Пример #1
0
func (d *Dir) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (fs.Node, fs.Handle, error) {
	d.Lock()
	defer d.Unlock()

	log.Printf("(*Dir) Create, name=%s", req.Name)

	if exists := d.exists(req.Name); exists {
		log.Println("Create open ERR: EEXIST")
		return nil, nil, fuse.EEXIST
	}
	path := filepath.Join(d.path, req.Name)
	fHandler, err := os.OpenFile(path, int(req.Flags), req.Mode)
	if err != nil {
		log.Println("Create open ERR: ", err)
		return nil, nil, err
	}

	n := d.fs.newFile(path, req.Mode)
	n.fs = d.fs
	n.handler = fHandler

	resp.Attr = n.attr

	return n, n, nil
}
// Creates a regular file in dir with the attributes supplied in req
func (dir *Directory) Create(req *fuse.CreateRequest, resp *fuse.CreateResponse, intr fs.Intr) (fs.Node, fs.Handle, fuse.Error) {
	if strings.Contains(req.Name, "@") {
		return nil, nil, fuse.EPERM
	}
	filesystem.Lock(dir)
	defer filesystem.Unlock(dir)
	util.P_out(req.String())
	rval := new(File)
	rval.InitFile(req.Name, req.Mode, dir)
	rval.Attrs.Gid = req.Gid
	rval.Attrs.Uid = req.Uid
	dir.setChild(rval)
	resp.Attr = rval.Attr()
	resp.Node = fuse.NodeID(rval.Attr().Inode)
	rval.dirty = true
	dir.dirty = true
	return rval, rval, nil
}
Пример #3
0
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
}
Пример #4
0
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
}
Пример #5
0
//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
}