func (n *Server) Open(req *go9ps.Req) { fmt.Printf("Open fid=%d wname=%v\n", req.Tc.Fid, req.Tc.Wname) if req.Fid.Aux == nil { req.RespondError(go9ps.Enoent) return } e, ok := req.Fid.Aux.(*FileEntry) if !ok { req.RespondError(go9ps.Enoent) return } if e.h == nil { req.RespondError(go9ps.Enoent) return } if e.h.IsDir() { // FIXME: wrap dir operations in a readwriter to the 9p dir entry serialized format. } else { var err error e.openrw, err = e.h.OpenRW() if err != nil { req.RespondError(err) return } } qids := newQids(req.Tc.Mode) req.RespondRopen(&qids[0], 0) }
func (*Ufs) Stat(req *srv.Req) { fid := req.Fid.Aux.(*Fid) err := fid.stat() if err != nil { req.RespondError(err) return } st := dir2Dir(fid.path, fid.st, req.Conn.Dotu, req.Conn.Srv.Upool) req.RespondRstat(st) }
func (n *Server) Walk(req *go9ps.Req) { fmt.Printf("Walk fid=%d wname=%v newfid=%d\n", req.Tc.Fid, req.Tc.Wname, req.Tc.Newfid) e, ok := req.Fid.Aux.(*FileEntry) if !ok { req.RespondError(go9ps.Enoent) return } if e.h == nil { req.RespondError(go9ps.Enoent) return } newH, err := e.h.WalkDir(req.Tc.Wname...) if err != nil { req.RespondError(err) return } req.Newfid.Aux = &FileEntry{ h: newH, } req.RespondRwalk(newQids(req.Tc.Mode)) }
func (*Ufs) Remove(req *srv.Req) { fid := req.Fid.Aux.(*Fid) err := fid.stat() if err != nil { req.RespondError(err) return } e := os.Remove(fid.path) if e != nil { req.RespondError(toError(e)) return } req.RespondRremove() }
func (*Ufs) Write(req *srv.Req) { fid := req.Fid.Aux.(*Fid) tc := req.Tc err := fid.stat() if err != nil { req.RespondError(err) return } n, e := fid.file.WriteAt(tc.Data, int64(tc.Offset)) if e != nil { req.RespondError(toError(e)) return } req.RespondRwrite(uint32(n)) }
func (*Ufs) Open(req *srv.Req) { fid := req.Fid.Aux.(*Fid) tc := req.Tc err := fid.stat() if err != nil { req.RespondError(err) return } var e error fid.file, e = os.OpenFile(fid.path, omode2uflags(tc.Mode), 0) if e != nil { req.RespondError(toError(e)) return } req.RespondRopen(dir2Qid(fid.st), 0) }
func (*Ufs) Walk(req *srv.Req) { fid := req.Fid.Aux.(*Fid) tc := req.Tc err := fid.stat() if err != nil { req.RespondError(err) return } if req.Newfid.Aux == nil { req.Newfid.Aux = new(Fid) } nfid := req.Newfid.Aux.(*Fid) wqids := make([]go9p.Qid, len(tc.Wname)) path := fid.path i := 0 for ; i < len(tc.Wname); i++ { p := path + "/" + tc.Wname[i] st, err := os.Lstat(p) if err != nil { if i == 0 { req.RespondError(Enoent) return } break } wqids[i] = *dir2Qid(st) path = p } nfid.path = path req.RespondRwalk(wqids[0:i]) }
func (*Ufs) Attach(req *srv.Req) { if req.Afid != nil { req.RespondError(srv.Enoauth) return } tc := req.Tc fid := new(Fid) if len(tc.Aname) == 0 { fid.path = *root } else { fid.path = tc.Aname } req.Fid.Aux = fid err := fid.stat() if err != nil { req.RespondError(err) return } qid := dir2Qid(fid.st) req.RespondRattach(qid) }
func (n *Server) Wstat(req *go9ps.Req) { fmt.Printf("Wstat fid=%d wname=%v newfid=%d\n", req.Tc.Fid, req.Tc.Wname, req.Tc.Newfid) req.RespondError(go9ps.Enoent) }
func (n *Server) Attach(req *go9ps.Req) { fmt.Printf("Attach fid=%d\n", req.Tc.Fid) qids := newQids(req.Tc.Mode) req.RespondRattach(&qids[0]) }
func (n *Server) Clunk(req *go9ps.Req) { fmt.Printf("Clunk fid=%d\n", req.Tc.Fid) req.RespondRclunk() }
func (*Ufs) Wstat(req *srv.Req) { fid := req.Fid.Aux.(*Fid) err := fid.stat() if err != nil { req.RespondError(err) return } dir := &req.Tc.Dir if dir.Mode != 0xFFFFFFFF { mode := dir.Mode & 0777 if req.Conn.Dotu { if dir.Mode&go9p.DMSETUID > 0 { mode |= syscall.S_ISUID } if dir.Mode&go9p.DMSETGID > 0 { mode |= syscall.S_ISGID } } e := os.Chmod(fid.path, os.FileMode(mode)) if e != nil { req.RespondError(toError(e)) return } } uid, gid := go9p.NOUID, go9p.NOUID if req.Conn.Dotu { uid = dir.Uidnum gid = dir.Gidnum } // Try to find local uid, gid by name. if (dir.Uid != "" || dir.Gid != "") && !req.Conn.Dotu { uid, err = lookup(dir.Uid, false) if err != nil { req.RespondError(err) return } // BUG(akumar): Lookup will never find gids // corresponding to group names, because // it only operates on user names. gid, err = lookup(dir.Gid, true) if err != nil { req.RespondError(err) return } } if uid != go9p.NOUID || gid != go9p.NOUID { e := os.Chown(fid.path, int(uid), int(gid)) if e != nil { req.RespondError(toError(e)) return } } if dir.Name != "" { path := fid.path[0:strings.LastIndex(fid.path, "/")+1] + "/" + dir.Name err := syscall.Rename(fid.path, path) if err != nil { req.RespondError(toError(err)) return } fid.path = path } if dir.Length != 0xFFFFFFFFFFFFFFFF { e := os.Truncate(fid.path, int64(dir.Length)) if e != nil { req.RespondError(toError(e)) return } } // If either mtime or atime need to be changed, then // we must change both. if dir.Mtime != ^uint32(0) || dir.Atime != ^uint32(0) { mt, at := time.Unix(int64(dir.Mtime), 0), time.Unix(int64(dir.Atime), 0) if cmt, cat := (dir.Mtime == ^uint32(0)), (dir.Atime == ^uint32(0)); cmt || cat { st, e := os.Stat(fid.path) if e != nil { req.RespondError(toError(e)) return } switch cmt { case true: mt = st.ModTime() default: at = atime(st.Sys().(*syscall.Stat_t)) } } e := os.Chtimes(fid.path, at, mt) if e != nil { req.RespondError(toError(e)) return } } req.RespondRwstat() }
func (*Ufs) Clunk(req *srv.Req) { req.RespondRclunk() }
func (*Ufs) Read(req *srv.Req) { fid := req.Fid.Aux.(*Fid) tc := req.Tc rc := req.Rc err := fid.stat() if err != nil { req.RespondError(err) return } go9p.InitRread(rc, tc.Count) var count int var e error if fid.st.IsDir() { b := rc.Data if tc.Offset == 0 { fid.file.Close() fid.file, e = os.OpenFile(fid.path, omode2uflags(req.Fid.Omode), 0) if e != nil { req.RespondError(toError(e)) return } } for len(b) > 0 { if fid.dirs == nil { fid.dirs, e = fid.file.Readdir(16) if e != nil && e != io.EOF { req.RespondError(toError(e)) return } if len(fid.dirs) == 0 { break } } var i int for i = 0; i < len(fid.dirs); i++ { path := fid.path + "/" + fid.dirs[i].Name() st := dir2Dir(path, fid.dirs[i], req.Conn.Dotu, req.Conn.Srv.Upool) sz := go9p.PackDir(st, b, req.Conn.Dotu) if sz == 0 { break } b = b[sz:] count += sz } if i < len(fid.dirs) { fid.dirs = fid.dirs[i:] break } else { fid.dirs = nil } } } else { count, e = fid.file.ReadAt(rc.Data, int64(tc.Offset)) if e != nil && e != io.EOF { req.RespondError(toError(e)) return } } go9p.SetRreadCount(rc, uint32(count)) req.Respond() }
func (*Ufs) Create(req *srv.Req) { fid := req.Fid.Aux.(*Fid) tc := req.Tc err := fid.stat() if err != nil { req.RespondError(err) return } path := fid.path + "/" + tc.Name var e error = nil var file *os.File = nil switch { case tc.Perm&go9p.DMDIR != 0: e = os.Mkdir(path, os.FileMode(tc.Perm&0777)) case tc.Perm&go9p.DMSYMLINK != 0: e = os.Symlink(tc.Ext, path) case tc.Perm&go9p.DMLINK != 0: n, e := strconv.ParseUint(tc.Ext, 10, 0) if e != nil { break } ofid := req.Conn.FidGet(uint32(n)) if ofid == nil { req.RespondError(srv.Eunknownfid) return } e = os.Link(ofid.Aux.(*Fid).path, path) ofid.DecRef() case tc.Perm&go9p.DMNAMEDPIPE != 0: case tc.Perm&go9p.DMDEVICE != 0: req.RespondError(&go9p.Error{"not implemented", go9p.EIO}) return default: var mode uint32 = tc.Perm & 0777 if req.Conn.Dotu { if tc.Perm&go9p.DMSETUID > 0 { mode |= syscall.S_ISUID } if tc.Perm&go9p.DMSETGID > 0 { mode |= syscall.S_ISGID } } file, e = os.OpenFile(path, omode2uflags(tc.Mode)|os.O_CREATE, os.FileMode(mode)) } if file == nil && e == nil { file, e = os.OpenFile(path, omode2uflags(tc.Mode), 0) } if e != nil { req.RespondError(toError(e)) return } fid.path = path fid.file = file err = fid.stat() if err != nil { req.RespondError(err) return } req.RespondRcreate(dir2Qid(fid.st), 0) }