Example #1
0
// Create adds either a synthetic dir or file, depending on the file
// permissions, if the create is permitted and a file with that name doesn't
// already exist. It also updates mtime, mtime and version for the dir.
func (d *SyntheticDir) Create(user, name string, perms qp.FileMode) (File, error) {
	d.Lock()
	defer d.Unlock()
	owner := d.UID == user
	if !PermCheck(owner, false, d.Permissions, qp.OWRITE) {
		return nil, ErrPermissionDenied
	}

	_, ok := d.Tree[name]
	if ok {
		return nil, ErrFileAlreadyExists
	}

	var f File
	if perms&qp.DMDIR != 0 {
		perms = perms & (^qp.FileMode(0777) | (d.Permissions & 0777))
		f = NewSyntheticDir(name, perms, d.UID, d.GID)
	} else {
		perms = perms & (^qp.FileMode(0666) | (d.Permissions & 0666))
		f = NewSyntheticFile(name, perms, d.UID, d.GID)
	}

	d.Tree[name] = f

	d.Mtime = time.Now()
	d.Atime = d.Mtime
	d.Version++
	return f, nil
}
Example #2
0
func emptyStat() qp.Stat {
	return qp.Stat{
		Type:   ^uint16(0),
		Dev:    ^uint32(0),
		Mode:   ^qp.FileMode(0),
		Atime:  ^uint32(0),
		Mtime:  ^uint32(0),
		Length: ^uint64(0),
	}
}
Example #3
0
// Create creates either a file or a directory at the specified path. It fails
// if the file already exists, or permissions did not permit it.
func (c *SimpleClient) Create(name string, directory bool) error {
	if c.root == nil {
		return ErrSimpleClientNotStarted
	}
	dir := path.Dir(name)
	file := path.Base(name)

	fid, _, err := c.walkTo(dir)
	if err != nil {
		return err
	}
	defer fid.Clunk()

	perms := qp.FileMode(0755)
	if directory {
		perms |= qp.DMDIR
	}

	_, _, err = fid.Create(file, perms, qp.OREAD)
	if err != nil {
		return err
	}
	return nil
}
Example #4
0
func setStat(user string, e trees.File, parent trees.Dir, nstat qp.Stat) error {
	ostat, err := e.Stat()
	if err != nil {
		return err
	}

	length := false
	name := false
	mode := false
	owner := false

	if nstat.Type != ^uint16(0) && nstat.Type != ostat.Type {
		return errors.New("it is illegal to modify type")
	}
	if nstat.Dev != ^uint32(0) && nstat.Dev != ostat.Dev {
		return errors.New("it is illegal to modify dev")
	}
	if nstat.MUID != "" && nstat.MUID != ostat.MUID {
		return errors.New("it is illegal to modify muid")
	}
	if nstat.Atime != ^uint32(0) && nstat.Atime != ostat.Atime {
		return errors.New("it is illegal to modify atime")
	}
	if parent == nil && nstat.Name != "" && nstat.Name != ostat.Name {
		return errors.New("it is illegal to rename root")
	}
	if nstat.Length != ^uint64(0) && nstat.Length != ostat.Length {
		if ostat.Mode&qp.DMDIR != 0 {
			return errors.New("cannot set length of directory")
		}
		if nstat.Length > ostat.Length {
			return errors.New("cannot extend length")
		}
		length = true
	}
	if nstat.Name != "" && nstat.Name != ostat.Name {
		name = true
	}
	if (nstat.UID != "" && nstat.UID != ostat.UID) || (nstat.GID != "" && nstat.GID != ostat.GID) {
		owner = true
	}
	if nstat.Mode != ^qp.FileMode(0) && nstat.Mode != ostat.Mode {
		mode = true
	}

	if nstat.Mtime != ^uint32(0) && nstat.Mtime != ostat.Mtime {
		// We ignore mtime changes ATM. Only owner can change mtime.
	}

	if mode {
		if err := e.SetMode(user, ostat.Mode&qp.DMDIR | nstat.Mode & ^qp.DMDIR); err != nil {
			return err
		}
	}
	if owner {
		if err := e.SetOwner(user, nstat.UID, nstat.GID); err != nil {
			e.SetMode(user, ostat.Mode)
			return err
		}
	}
	if name {
		if err := parent.Rename(user, ostat.Name, nstat.Name); err != nil {
			e.SetMode(user, ostat.Mode)
			e.SetOwner(user, ostat.UID, ostat.GID)
			return err
		}
	}
	if length {
		if err := e.SetLength(user, nstat.Length); err != nil {
			e.SetMode(user, ostat.Mode)
			e.SetOwner(user, ostat.UID, ostat.GID)
			parent.Rename(user, nstat.Name, ostat.Name)
			return err
		}
	}
	return nil
}