numfs.go (3098B)
1 package main 2 3 import ( 4 "bytes" 5 "flag" 6 "fmt" 7 "io" 8 "log" 9 "net" 10 "os" 11 12 "lib9p" 13 ) 14 15 var root *numFile 16 17 func init() { 18 fsys := new(numFS) 19 root = &numFile{ 20 fs: fsys, 21 id: -1, 22 reader: nil, 23 children: []*numFile{ 24 &numFile{fsys, 0, bytes.NewReader([]byte("0\n")), nil}, 25 &numFile{fsys, 1, bytes.NewReader([]byte("1\n")), nil}, 26 &numFile{fsys, 2, bytes.NewReader([]byte("2\n")), nil}, 27 &numFile{fsys, 3, bytes.NewReader([]byte("3\n")), nil}, 28 }, 29 } 30 } 31 32 type numFS struct{} 33 34 func (fsys *numFS) Root() lib9p.File { 35 return root 36 } 37 38 type numFile struct { 39 fs *numFS 40 id int 41 reader *bytes.Reader 42 children []*numFile 43 } 44 45 func (f *numFile) Fsys() lib9p.FS { return f.fs } 46 47 func (f *numFile) Stat() (*lib9p.FileInfo, error) { 48 var stat lib9p.Stat 49 stat.Type = 0 50 stat.Dev = 0 51 if f.id == -1 { 52 stat.Qid = lib9p.Qid{ 53 Type: lib9p.QTDIR, 54 Vers: 0, 55 Path: ^uint64(0), 56 } 57 } else { 58 stat.Qid = lib9p.Qid{ 59 Type: lib9p.QTFILE, 60 Vers: 0, 61 Path: uint64(f.id), 62 } 63 } 64 var mode lib9p.FileMode 65 if f.id == -1 { 66 mode |= lib9p.DMDIR 67 } 68 mode |= 0444 69 stat.Mode = mode 70 stat.Atime = 0 71 stat.Mtime = 0 72 var length int64 73 if f.id == -1 { 74 length = 0 75 } else { 76 length = f.reader.Size() 77 } 78 stat.Length = length 79 stat.Name = fmt.Sprintf("%d", f.id) 80 stat.Uid = "kenji" 81 stat.Gid = "kenji" 82 stat.Muid = "kenji" 83 return &lib9p.FileInfo{stat}, nil 84 } 85 86 func (f *numFile) Qid() lib9p.Qid { 87 var qid lib9p.Qid 88 if f.id == -1 { 89 qid = lib9p.Qid{ 90 Type: lib9p.QTDIR, 91 Vers: 0, 92 Path: ^uint64(0), 93 } 94 } else { 95 qid = lib9p.Qid{ 96 Type: lib9p.QTFILE, 97 Vers: 0, 98 Path: uint64(f.id), 99 } 100 } 101 return qid 102 } 103 104 func (f *numFile) Read(p []byte) (int, error) { 105 if f.id == -1 { 106 return 0, fmt.Errorf("is a directory") 107 } 108 return f.reader.Read(p) 109 } 110 111 func (f *numFile) ReadAt(p []byte, off int64) (n int, err error) { 112 if f.id == -1 { 113 return 0, fmt.Errorf("is a directory") 114 } 115 return f.reader.ReadAt(p, off) 116 } 117 118 func (f *numFile) Open(mode lib9p.OpenMode) error { 119 return nil 120 } 121 122 func (f *numFile) Close() error { 123 f.reader.Seek(0, io.SeekStart) 124 return nil 125 } 126 127 func (f *numFile) PathName() string { 128 if f.id == -1 { 129 return "." 130 } 131 return fmt.Sprintf("%d", f.id) 132 } 133 134 135 func (f *numFile) Parent() (lib9p.File, error) { return root, nil } 136 137 func (f *numFile) Child() ([]lib9p.File, error) { 138 if f.id != -1 { 139 return nil, fmt.Errorf("not a directory") 140 } 141 children := make([]lib9p.File, len(f.children)) 142 for i, c := range f.children { 143 children[i] = c 144 } 145 return children, nil 146 } 147 148 var dFlag = flag.Bool("D", false, "Prints chatty message to the stderr.") 149 150 func main() { 151 flag.Parse() 152 153 if flag.NArg() != 0 { 154 fmt.Fprintf(os.Stderr, "usage: %s [-D]\n", os.Args[0]) 155 os.Exit(1) 156 } 157 158 listener, err := net.Listen("tcp", "127.0.0.1:5640") 159 if err != nil { 160 log.Fatalf("listen tcp: %v", err) 161 } 162 163 for { 164 conn, err := listener.Accept() 165 if err != nil { 166 log.Printf("accept connection: %v", err) 167 continue 168 } 169 170 go handle(conn, &numFS{}) 171 } 172 } 173 174 func handle(conn net.Conn, fs *numFS) { 175 srv := lib9p.NewServer(fs, 8*1024, conn, conn) 176 if *dFlag { 177 srv.Chatty() 178 } 179 srv.Serve() 180 }