Esempio n. 1
0
File: file.go Progetto: droyo/styx
// Stat produces a styxproto.Stat from an open file. If the value
// provides a Stat method matching that of os.File, that is used.
// Otherwise, the styxfile package determines the file's attributes
// based on other characteristics.
func Stat(buf []byte, file Interface, name string, qid styxproto.Qid) (styxproto.Stat, error) {
	var (
		fi  os.FileInfo
		err error
	)
	type hasStat interface {
		Stat() (os.FileInfo, error)
	}
	if v, ok := file.(hasStat); ok {
		fi, err = v.Stat()
		if err != nil {
			return nil, err
		}
	} else {
		fi = statGuess{file, name, qid.Type()}
	}
	uid, gid, muid := sys.FileOwner(fi)
	stat, _, err := styxproto.NewStat(buf, fi.Name(), uid, gid, muid)
	if err != nil {
		return nil, err
	}
	stat.SetLength(fi.Size())
	stat.SetMode(Mode9P(fi.Mode()))
	stat.SetAtime(uint32(fi.ModTime().Unix()))
	stat.SetMtime(uint32(fi.ModTime().Unix()))
	stat.SetQid(qid)
	return stat, nil
}
Esempio n. 2
0
// Rstat responds to a succesful Tstat request. The styx package will
// translate the os.FileInfo value into the appropriate 9P structure. Rstat
// will attempt to resolve the names of the file's owner and group. If
// that cannot be done, an empty string is sent. If err is non-nil, and error
// is sent to the client instead.
func (t Tstat) Rstat(info os.FileInfo, err error) {
	if err != nil {
		t.Rerror("%s", err)
		return
	}
	buf := make([]byte, styxproto.MaxStatLen)
	uid, gid, muid := sys.FileOwner(info)
	name := info.Name()
	if name == "/" {
		name = "."
	}
	stat, _, err := styxproto.NewStat(buf, name, uid, gid, muid)
	if err != nil {
		// should never happen
		panic(err)
	}
	mode := styxfile.Mode9P(info.Mode())
	stat.SetLength(info.Size())
	stat.SetMode(mode)
	stat.SetAtime(uint32(info.ModTime().Unix())) // TODO: get atime
	stat.SetMtime(uint32(info.ModTime().Unix()))
	stat.SetQid(t.session.conn.qid(t.Path(), styxfile.QidType(mode)))
	t.session.unhandled = false
	if t.session.conn.clearTag(t.tag) {
		t.session.conn.Rstat(t.tag, stat)
	}
}
Esempio n. 3
0
func (s *Session) handleTstat(cx context.Context, msg styxproto.Tstat, file file) bool {
	buf := make([]byte, styxproto.MaxStatLen)
	if file.auth {
		stat, _, err := styxproto.NewStat(buf, "", "", "", "")
		if err != nil {
			// input is not user-controlled, this should
			// never happen
			panic(err)
		}
		stat.SetMode(styxproto.DMAUTH)
		stat.SetQid(s.conn.qid("", styxproto.QTAUTH))
		s.conn.clearTag(msg.Tag())
		s.conn.Rstat(msg.Tag(), stat)
		s.conn.Flush()
	} else if file.rwc != nil {
		s.conn.clearTag(msg.Tag())
		if qid, ok := s.conn.qidpool.Get(file.name); !ok {
			s.conn.Rerror(msg.Tag(), "qid for %s not found", file.name)
		} else if stat, err := styxfile.Stat(buf, file.rwc, file.name, qid); err != nil {
			s.conn.Rerror(msg.Tag(), "%s", err)
		} else {
			s.conn.Rstat(msg.Tag(), stat)
		}
		s.conn.Flush()
	} else {
		s.requests <- Tstat{
			reqInfo: newReqInfo(cx, s, msg, file.name),
		}
	}
	return true
}
Esempio n. 4
0
func ExampleNewStat() {
	buf := make([]byte, 100)
	s, buf, err := styxproto.NewStat(buf, "messages.log", "root", "wheel", "")
	if err != nil {
		log.Fatal(err)
	}
	s.SetLength(309)
	s.SetMode(0640)
	fmt.Println(s)

	// Output: type=0 dev=0 qid="type=0 ver=0 path=0" mode=640 atime=0 mtime=0 length=309 name="messages.log" uid="root" gid="wheel" muid=""
}
Esempio n. 5
0
func blankStat(name, uid, gid string) styxproto.Stat {
	buf := make([]byte, styxproto.MaxStatLen)
	stat, _, err := styxproto.NewStat(buf, name, uid, gid, uid)
	if err != nil {
		panic(err)
	}

	stat.SetAtime(maxuint32)
	stat.SetMtime(maxuint32)
	stat.SetDev(maxuint32)
	stat.SetLength(-1)
	stat.SetMode(maxuint32)
	for i := range stat.Qid() {
		stat.Qid()[i] = 0xff
	}
	stat.SetType(maxuint16)
	return stat
}
Esempio n. 6
0
File: dir.go Progetto: droyo/styx
func marshalStats(buf []byte, files []os.FileInfo, dir string, pool *qidpool.Pool) (int, error) {
	var (
		stat styxproto.Stat
		n    = 0
		err  error
	)
	for _, fi := range files {
		uid, gid, muid := sys.FileOwner(fi)
		stat, buf, err = styxproto.NewStat(buf, fi.Name(), uid, gid, muid)
		if err != nil {
			break
		}
		n += len(stat)
		mode := Mode9P(fi.Mode())
		qtype := QidType(mode)

		stat.SetMtime(uint32(fi.ModTime().Unix()))
		stat.SetAtime(stat.Mtime())
		stat.SetLength(fi.Size())
		stat.SetMode(mode)
		stat.SetQid(pool.Put(path.Join(dir, fi.Name()), qtype))
	}
	return n, err
}