9fans.net/go@v0.0.5/plan9/dir.go (about) 1 package plan9 2 3 import ( 4 "fmt" 5 "strconv" 6 ) 7 8 type ProtocolError string 9 10 func (e ProtocolError) Error() string { 11 return string(e) 12 } 13 14 const ( 15 STATMAX = 65535 16 ) 17 18 type Dir struct { 19 Type uint16 20 Dev uint32 21 Qid Qid 22 Mode Perm 23 Atime uint32 24 Mtime uint32 25 Length uint64 26 Name string 27 Uid string 28 Gid string 29 Muid string 30 } 31 32 var nullDir = Dir{ 33 ^uint16(0), 34 ^uint32(0), 35 Qid{^uint64(0), ^uint32(0), ^uint8(0)}, 36 ^Perm(0), 37 ^uint32(0), 38 ^uint32(0), 39 ^uint64(0), 40 "", 41 "", 42 "", 43 "", 44 } 45 46 func (d *Dir) Null() { 47 *d = nullDir 48 } 49 50 func pdir(b []byte, d *Dir) []byte { 51 n := len(b) 52 b = pbit16(b, 0) // length, filled in later 53 b = pbit16(b, d.Type) 54 b = pbit32(b, d.Dev) 55 b = pqid(b, d.Qid) 56 b = pperm(b, d.Mode) 57 b = pbit32(b, d.Atime) 58 b = pbit32(b, d.Mtime) 59 b = pbit64(b, d.Length) 60 b = pstring(b, d.Name) 61 b = pstring(b, d.Uid) 62 b = pstring(b, d.Gid) 63 b = pstring(b, d.Muid) 64 pbit16(b[0:n], uint16(len(b)-(n+2))) 65 return b 66 } 67 68 func (d *Dir) Bytes() ([]byte, error) { 69 return pdir(nil, d), nil 70 } 71 72 func UnmarshalDir(b []byte) (d *Dir, err error) { 73 defer func() { 74 if v := recover(); v != nil { 75 d = nil 76 err = ProtocolError("malformed Dir") 77 } 78 }() 79 80 n, b := gbit16(b) 81 if int(n) != len(b) { 82 panic(1) 83 } 84 85 d = new(Dir) 86 d.Type, b = gbit16(b) 87 d.Dev, b = gbit32(b) 88 d.Qid, b = gqid(b) 89 d.Mode, b = gperm(b) 90 d.Atime, b = gbit32(b) 91 d.Mtime, b = gbit32(b) 92 d.Length, b = gbit64(b) 93 d.Name, b = gstring(b) 94 d.Uid, b = gstring(b) 95 d.Gid, b = gstring(b) 96 d.Muid, b = gstring(b) 97 98 if len(b) != 0 { 99 panic(1) 100 } 101 return d, nil 102 } 103 104 func (d *Dir) String() string { 105 return fmt.Sprintf("'%s' '%s' '%s' '%s' q %v m %#o at %d mt %d l %d t %d d %d", 106 d.Name, d.Uid, d.Gid, d.Muid, d.Qid, d.Mode, 107 d.Atime, d.Mtime, d.Length, d.Type, d.Dev) 108 } 109 110 func dumpsome(b []byte) string { 111 if len(b) > 64 { 112 b = b[0:64] 113 } 114 115 printable := true 116 for _, c := range b { 117 if (c != 0 && c != '\n' && c != '\t' && c < ' ') || c > 127 { 118 printable = false 119 break 120 } 121 } 122 123 if printable { 124 return strconv.Quote(string(b)) 125 } 126 return fmt.Sprintf("%x", b) 127 } 128 129 type Perm uint32 130 131 type permChar struct { 132 bit Perm 133 c rune 134 } 135 136 var permChars = []permChar{ 137 permChar{DMDIR, 'd'}, 138 permChar{DMAPPEND, 'a'}, 139 permChar{DMAUTH, 'A'}, 140 permChar{DMDEVICE, 'D'}, 141 permChar{DMSOCKET, 'S'}, 142 permChar{DMNAMEDPIPE, 'P'}, 143 permChar{0, '-'}, 144 permChar{DMEXCL, 'l'}, 145 permChar{DMSYMLINK, 'L'}, 146 permChar{0, '-'}, 147 permChar{0400, 'r'}, 148 permChar{0, '-'}, 149 permChar{0200, 'w'}, 150 permChar{0, '-'}, 151 permChar{0100, 'x'}, 152 permChar{0, '-'}, 153 permChar{0040, 'r'}, 154 permChar{0, '-'}, 155 permChar{0020, 'w'}, 156 permChar{0, '-'}, 157 permChar{0010, 'x'}, 158 permChar{0, '-'}, 159 permChar{0004, 'r'}, 160 permChar{0, '-'}, 161 permChar{0002, 'w'}, 162 permChar{0, '-'}, 163 permChar{0001, 'x'}, 164 permChar{0, '-'}, 165 } 166 167 func (p Perm) String() string { 168 s := "" 169 did := false 170 for _, pc := range permChars { 171 if p&pc.bit != 0 { 172 did = true 173 s += string(pc.c) 174 } 175 if pc.bit == 0 { 176 if !did { 177 s += string(pc.c) 178 } 179 did = false 180 } 181 } 182 return s 183 } 184 185 func gperm(b []byte) (Perm, []byte) { 186 p, b := gbit32(b) 187 return Perm(p), b 188 } 189 190 func pperm(b []byte, p Perm) []byte { 191 return pbit32(b, uint32(p)) 192 } 193 194 type Qid struct { 195 Path uint64 196 Vers uint32 197 Type uint8 198 } 199 200 func (q Qid) String() string { 201 t := "" 202 if q.Type&QTDIR != 0 { 203 t += "d" 204 } 205 if q.Type&QTAPPEND != 0 { 206 t += "a" 207 } 208 if q.Type&QTEXCL != 0 { 209 t += "l" 210 } 211 if q.Type&QTAUTH != 0 { 212 t += "A" 213 } 214 return fmt.Sprintf("(%.16x %d %s)", q.Path, q.Vers, t) 215 } 216 217 func gqid(b []byte) (Qid, []byte) { 218 var q Qid 219 q.Type, b = gbit8(b) 220 q.Vers, b = gbit32(b) 221 q.Path, b = gbit64(b) 222 return q, b 223 } 224 225 func pqid(b []byte, q Qid) []byte { 226 b = pbit8(b, q.Type) 227 b = pbit32(b, q.Vers) 228 b = pbit64(b, q.Path) 229 return b 230 }