1extern crate game_kernel_utils;
2
3use std::cell::{Ref, RefCell};
4use std::collections::HashMap;
5use std::io::{Read, Seek, Write};
6use std::ops::{Deref, DerefMut};
7use std::sync::{Arc, RwLock, RwLockReadGuard};
8
9use game_kernel_utils::{MapAbstract, MapMap};
10
11mod path;
12
13pub trait OpenVFile: OpenVROFile + Write {}
14pub trait OpenVROFile: Read + Seek {}
15
16trait VFile: VROFile {
17 fn open_rw(&self) -> Box<dyn OpenVROFile>;
18}
19
20trait VROFile: AsVROFile {
21 fn open(&mut self) -> Box<dyn OpenVROFile>;
22}
23
24trait AsVROFile {
25 fn as_ro(&self) -> &VROFile;
26}
27
28impl<T: VROFile> AsVROFile for T {
29 fn as_ro(&self) -> &VROFile {
30 self
31 }
32}
33
34enum FsObjTypes {
35 file(Box<VFile>),
36 ro_file(Box<VROFile>),
37 directory(Directory),
38}
39
40#[derive(Clone)]
41pub enum Permissions {
42 Read,
43 ReadWrite,
44}
45
46pub struct FsObject {
47 obj_type: FsObjTypes,
49 name: String,
50 acl: HashMap<u32, Permissions>,
51}
52
53impl FsObject {
54 pub fn get_acl(&self) -> &HashMap<u32, Permissions> {
55 &self.acl
56 }
57
58 pub fn get_permissions(&self, user: &u32) -> Option<Permissions> {
59 self.get_acl().get(user).map(|t| (*t).clone())
60 }
61
62 pub fn can_read(&self, user: &u32) -> bool {
63 self.get_permissions(user).is_some()
64 }
65
66 pub fn can_write(&self, user: &u32) -> bool {
67 if let Some(Permissions::ReadWrite) = self.get_permissions(user) {
68 true
69 } else {
70 false
71 }
72 }
73}
74
75pub struct FileMeta {
76 name: String,
77 ro: bool,
78 acl: HashMap<u32, Permissions>,
79}
80
81pub struct Directory {
82 contents: HashMap<String, Arc<FsObject>>,
83 driver: Option<Box<dyn FsDriver>>,
84 driver_path: Option<path::Path>,
85 read_only: bool,
86}
87
88impl Directory {
89 pub fn new() -> Self {
90 Self {
91 contents: HashMap::new(),
92 driver: None,
93 driver_path: None,
94 read_only: false,
95 }
96 }
97
98 pub fn get_contents(&self) -> HashMap<String, Arc<FsObject>> {
99 self.contents.clone()
100 }
101
102 pub fn get_contents_mut(&mut self) -> HashMap<String, Arc<FsObject>> {
103 self.contents.clone()
104 }
105
106 pub fn put_object(&mut self, obj: FsObject) -> Result<(), ()> {
107 if self.read_only {
108 return Err(());
109 }
110
111 if let (Some(ref mut driver), Some(ref d_path)) = (&mut self.driver, &self.driver_path) {
112 driver.put_object(&d_path, obj)
113 } else {
114 self.contents.insert(obj.name.clone(), Arc::new(obj));
115 Ok(())
116 }
117 }
118
119 pub fn new_file(&mut self, meta: FileMeta) -> Result<&FsObject, ()> {
120 if self.read_only || self.driver.is_none() {
121 return Err(());
122 }
123
124 if let (Some(driver), Some(path)) = (&mut self.driver, &self.driver_path) {
125 driver.put_new_object(meta, path)
126 } else {
127 Err(())
128 }
129 }
130}
131
132pub trait FsDriver {
133 fn get_root(&self) -> Directory;
134 fn put_object(&mut self, path: &path::Path, obj: FsObject) -> Result<(), ()>;
135 fn put_new_object<'a>(
136 &'a mut self,
137 meta: FileMeta,
138 path: &path::Path,
139 ) -> Result<&'a FsObject, ()>;
140}
141
142pub struct Vfs {
143 root: Arc<FsObject>,
144}
145
146impl Vfs {
147 pub fn get_object_mut(&mut self, path: &path::Path) -> Result<Arc<FsObject>, ()> {
155 let mut curr_obj = self.root.clone();
156 for obj_name in path.obj_name_iter() {
157 match (curr_obj.obj_type) {
158 FsObjTypes::directory(ref dir) => {
159 let contents = dir.get_contents();
160 if let Some(obj) = contents.get(obj_name) {
161 curr_obj = obj.clone();
162 } else {
163 return Err(());
164 }
165 }
166
167 _ => return Err(()),
168 }
169 }
170
171 Ok(curr_obj)
172 }
173
174 pub fn get_object(&self, path: &path::Path) -> Result<Arc<FsObject>, ()> {
175 let mut curr_obj = self.root.clone();
176 for obj_name in path.obj_name_iter() {
177 match (curr_obj.obj_type) {
178 FsObjTypes::directory(ref dir) => {
179 let contents = dir.get_contents();
180 if let Some(obj) = contents.get(obj_name) {
181 curr_obj = obj.clone();
182 } else {
183 return Err(());
184 }
185 }
186
187 _ => return Err(()),
188 }
189 }
190
191 Ok(curr_obj)
192 }
193
194 pub fn put_object(&mut self, path: path::Path) -> Result<(), ()> {
195 let (path, name) = path.split_at_base();
196 let mut curr_obj = self.root.clone();
197 for obj_name in path.obj_name_iter() {
198 match (curr_obj.obj_type) {
199 FsObjTypes::directory(ref dir) => {
200 let contents = dir.get_contents();
201 if let Some(obj) = contents.get(obj_name) {
202 curr_obj = obj.clone();
203 } else {
204 return Err(());
205 }
206 }
207
208 _ => return Err(()),
209 }
210 }
211
212 Ok(())
213 }
214}
215
216pub fn mount<T: FsDriver>(vfs: &mut Vfs, driver: T, path: path::Path) -> Result<(), ()> {
217 let driver_tobject = Box::new(driver);
218 let (base, filename) = path.split_at_base();
219 let mut b = vfs.get_object_mut(&base)?;
220 let dir = match (&mut Arc::get_mut(&mut b).ok_or(())?.obj_type) {
221 FsObjTypes::directory(dir) => Ok(dir),
222 _ => Err(()),
223 }?;
224 dir.put_object(FsObject {
225 obj_type: FsObjTypes::directory(driver_tobject.get_root()),
227 name: filename,
228 acl: HashMap::new(),
229 });
230 Ok(())
231}
232
233pub struct VfsHanfle<'a> {
234 user: u32,
235 vfs: &'a Vfs,
236}
237
238impl<'a> VfsHanfle<'a> {
239 pub fn new(user: u32, vfs: &'a mut Vfs) -> Self {
240 Self { user, vfs }
241 }
242
243 fn check_permission<T>(&self, obj: T, perm: Permissions) -> Result<T, ()>
244 where
245 T: Deref<Target = FsObject>,
246 {
247 match ((obj.can_read(&self.user), obj.can_write(&self.user), perm)) {
248 (true, _, Permissions::Read) => Ok(obj),
249 (true, true, Permissions::ReadWrite) => Ok(obj),
250 _ => Err(()),
251 }
252 }
253
254 fn check_permission_mut<T>(&self, obj: T, perm: Permissions) -> Result<T, ()>
255 where
256 T: DerefMut<Target = FsObject>,
257 {
258 match ((obj.can_read(&self.user), obj.can_write(&self.user), perm)) {
259 (true, _, Permissions::Read) => Ok(obj),
260 (true, true, Permissions::ReadWrite) => Ok(obj),
261 _ => Err(()),
262 }
263 }
264
265 fn own_acl(&self) -> HashMap<u32, Permissions> {
266 let mut acl = HashMap::new();
267 acl.insert(self.user, Permissions::ReadWrite);
268 acl
269 }
270
271 }