forked from sandia-minimega/minimega
-
Notifications
You must be signed in to change notification settings - Fork 1
/
ufs.go
100 lines (80 loc) · 2.05 KB
/
ufs.go
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
// Copyright (2014) Sandia Corporation.
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
package main
import (
log "minilog"
"net"
"os"
"path/filepath"
"ron"
"runtime"
"github.com/Harvey-OS/ninep/filesystem"
"github.com/Harvey-OS/ninep/protocol"
)
var rootFS struct {
// embed
*protocol.Server
running bool
// active connection, set when running
remote, local net.Conn
}
// ufsMessage handles a message from the server and relays it to UFS
func ufsMessage(m *ron.Message) {
switch m.UfsMode {
case ron.UFS_OPEN:
if rootFS.running {
log.Error("ufs is already running")
return
}
if rootFS.Server == nil {
log.Info("init rootFS")
root := "/"
if runtime.GOOS == "windows" {
// TODO: what if there is more that one volume?
root = filepath.VolumeName(os.Getenv("SYSTEMROOT")) + "\\"
}
fs, err := ufs.NewServer(ufs.Root(root), ufs.Trace(log.Debug))
if err != nil {
log.Error("unable to create file server: %v", err)
return
}
ps, err := protocol.NewServer(fs, protocol.Trace(log.Debug))
if err != nil {
log.Error("unable to create ninep server: %v", err)
return
}
rootFS.Server = ps
log.Info("init'd rootFS")
}
rootFS.running = true
rootFS.remote, rootFS.local = net.Pipe()
go ron.Trunk(rootFS.remote, client.UUID, ufsSendMessage)
log.Info("accepting tunneled connection")
if err := rootFS.Accept(rootFS.local); err != nil {
log.Error("ufs error: %v", err)
rootFS.running = false
}
case ron.UFS_CLOSE:
if !rootFS.running {
log.Error("ufs not running")
return
}
rootFS.running = false
rootFS.remote.Close()
case ron.UFS_DATA:
if !rootFS.running {
log.Error("ufs not running")
return
}
// relay the Tunnel data from ron
rootFS.remote.Write(m.Tunnel)
}
}
// ufsSendMessage tweaks the message generated by ron.Trunk before calling
// sendMessage.
func ufsSendMessage(m *ron.Message) error {
m.Type = ron.MESSAGE_UFS
m.UfsMode = ron.UFS_DATA
return sendMessage(m)
}