~moody/ninep

ref: 7b4c0484154111591a670ce6807bfbda3e864f36 ninep/dir.go -rw-r--r-- 2.8 KiB
7b4c0484 — Jacob Moody More docs touchup 5 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package ninep

import "encoding/binary"

const (
	//Bits for Qid.Type
	QTDir    = 0x80 //Directory
	QTAppend = 0x40 //Append only
	QTExcl   = 0x20 //Exclusive use
	QTMount  = 0x10 //Mounted channel
	QTAuth   = 0x08 //Auth file
	QTTemp   = 0x04 //Non WORM backed file
	QTFile   = 0    //Regular file
)

//Qid is the unique identification for a file.
type Qid struct {
	Path uint64 //Unique ID of specific file to a specific server.
	Vers uint32 //The version of the file, incremented for each change.
	Type byte   //The type of the file.
}

func (q *Qid) size() int { return 8 + 4 + 1 }

func (q *Qid) encode(b []byte) error {
	b[0] = q.Type
	binary.LittleEndian.PutUint32(b[1:], q.Vers)
	binary.LittleEndian.PutUint64(b[5:], q.Path)
	return nil
}

func (q *Qid) decode(data []byte) error {
	q.Type = data[0]
	q.Vers = binary.LittleEndian.Uint32(data[1:])
	q.Path = binary.LittleEndian.Uint64(data[5:])
	return nil
}

const (
	//Special bits for Dir.Mode
	DMDir    = 0x80000000 //Directory
	DMAppend = 0x40000000 //Append only
	DMExcl   = 0x20000000 //Exclusive use
	DMMount  = 0x10000000 //Mounted channel
	DMAuth   = 0x08000000 //Auth file
	DMTmp    = 0x04000000 //Non WORM backed file

	//Unix permissions in Dir.Mode, 3 sets for user, group and other.
	DMRead  = 0x4
	DMWrite = 0x2
	DMExec  = 0x1
)

//Dir contains all of the meta information for a file
//or directory.
type Dir struct {
	Qid
	Mode  uint32 //Unix permissions
	Atime uint32 //Unix time of last access
	Mtime uint32 //Unix time of last modification
	Len   uint64 //Length of file, directories set this to 0
	Name  string //Filename
	Uid   string //User Owner
	Gid   string //Group owner
	Muid  string //User that last modified this file
}

func (d *Dir) size() int {
	return 2 + 2 + 4 + 1 + 4 + 8 + 4 + 4 + 4 + 8 + 2 + len(d.Name) + 2 + len(d.Uid) + 2 + len(d.Gid) + 2 + len(d.Muid)
}

func (d *Dir) encode(b []byte) error {
	//the length embedded in to a Dir does not include the
	//length var itself
	binary.LittleEndian.PutUint16(b, uint16(d.size()-2))
	d.Qid.encode(b[8:])
	binary.LittleEndian.PutUint32(b[21:], d.Mode)
	binary.LittleEndian.PutUint32(b[25:], d.Atime)
	binary.LittleEndian.PutUint32(b[29:], d.Mtime)
	binary.LittleEndian.PutUint64(b[33:], d.Len)
	b = b[41:]

	n := putStr(b, d.Name)
	b = b[n:]
	n = putStr(b, d.Uid)
	b = b[n:]
	n = putStr(b, d.Gid)
	b = b[n:]
	putStr(b, d.Muid)

	return nil
}

func (d *Dir) decode(data []byte) error {
	d.Qid.decode(data[8:])
	d.Mode = binary.LittleEndian.Uint32(data[21:])
	d.Atime = binary.LittleEndian.Uint32(data[25:])
	d.Mtime = binary.LittleEndian.Uint32(data[29:])
	d.Len = binary.LittleEndian.Uint64(data[33:])
	data = data[41:]

	var n int

	n, d.Name = getStr(data)
	data = data[n:]
	n, d.Uid = getStr(data)
	data = data[n:]
	n, d.Gid = getStr(data)
	data = data[n:]
	_, d.Muid = getStr(data)

	return nil
}