Skip to main content

game_kernel_vfs/
lib.rs

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    //parent: Option<RefCell<Directory>>,
48    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 new() -> Self
148    {
149        Self{
150            root: Directory::new()
151        }
152    }*/
153
154    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        //parent: Some(RefCell::new(*dir)),
226        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    /*pub fn open(&self, path: &path::Path) -> Result<&'a VROFile, ()>
272    {
273        let obj = self.vfs.get_object(path)?;
274        if let FsObject{obj_type: FsObjTypes::file(file), ..} = self.check_permission(obj.as_ref(), Permissions::Read)?
275        {
276            Ok(file.as_ref().clone().as_ro())
277        }
278        else if let FsObject{obj_type: FsObjTypes::ro_file(file), ..} = self.check_permission(obj.as_ref(), Permissions::Read)?
279        {
280            Ok(file.as_ref().clone())
281        }
282        else
283        {
284            Err(())
285        }
286    }
287
288    pub fn open_rw(&self, path: path::Path) -> Result<&'a VFile, ()>
289    {
290        let obj = self.vfs.get_object(&path)?;
291        /*let obj = obj.unwrap_or({
292            let (base, filename) = path.split_at_base();
293            if let Ok(FsObject{obj_type: FsObjTypes::directory(dir), ..}) = self.check_permission_mut(self.vfs.get_object_mut(&base)?, Permissions::ReadWrite)
294            {
295                dir.new_file(FileMeta{name: filename, ro: false, acl: self.own_acl()})?
296            }
297            else
298            {
299                return Err(())
300            }
301        });*/
302        if let FsObject{obj_type: FsObjTypes::file(ref file), ..} = *self.check_permission(obj, Permissions::ReadWrite)?
303        {
304            Ok(file.as_ref())
305        }
306        else
307        {
308            Err(())
309        }
310    }*/
311}