1 use core::{mem, slice};
2 
3 use crate::data::*;
4 use crate::error::*;
5 use crate::flag::*;
6 use crate::number::*;
7 use crate::scheme::str_from_raw_parts;
8 
9 pub trait Scheme {
handle(&self, packet: &mut Packet)10     fn handle(&self, packet: &mut Packet) {
11         let res = match packet.a {
12             SYS_OPEN => if let Some(path) = unsafe { str_from_raw_parts(packet.b as *const u8, packet.c) } {
13                 self.open(path, packet.d, packet.uid, packet.gid)
14             } else {
15                 Err(Error::new(EINVAL))
16             },
17             SYS_CHMOD => if let Some(path) = unsafe { str_from_raw_parts(packet.b as *const u8, packet.c) } {
18                 self.chmod(path, packet.d as u16, packet.uid, packet.gid)
19             } else {
20                 Err(Error::new(EINVAL))
21             },
22             SYS_RMDIR => if let Some(path) = unsafe { str_from_raw_parts(packet.b as *const u8, packet.c) } {
23                 self.rmdir(path, packet.uid, packet.gid)
24             } else {
25                 Err(Error::new(EINVAL))
26             },
27             SYS_UNLINK => if let Some(path) = unsafe { str_from_raw_parts(packet.b as *const u8, packet.c) } {
28                 self.unlink(path, packet.uid, packet.gid)
29             } else {
30                 Err(Error::new(EINVAL))
31             },
32 
33             SYS_DUP => self.dup(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }),
34             SYS_READ => self.read(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }),
35             SYS_WRITE => self.write(packet.b, unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) }),
36             SYS_LSEEK => self.seek(packet.b, packet.c as isize, packet.d).map(|o| o as usize),
37             SYS_FCHMOD => self.fchmod(packet.b, packet.c as u16),
38             SYS_FCHOWN => self.fchown(packet.b, packet.c as u32, packet.d as u32),
39             SYS_FCNTL => self.fcntl(packet.b, packet.c, packet.d),
40             SYS_FEVENT => self.fevent(packet.b, EventFlags::from_bits_truncate(packet.c)).map(|f| f.bits()),
41             SYS_FMAP_OLD => if packet.d >= mem::size_of::<OldMap>() {
42                 self.fmap_old(packet.b, unsafe { &*(packet.c as *const OldMap) })
43             } else {
44                 Err(Error::new(EFAULT))
45             },
46             SYS_FMAP => if packet.d >= mem::size_of::<Map>() {
47                 self.fmap(packet.b, unsafe { &*(packet.c as *const Map) })
48             } else {
49                 Err(Error::new(EFAULT))
50             },
51             SYS_FUNMAP_OLD => self.funmap_old(packet.b),
52             SYS_FUNMAP => self.funmap(packet.b, packet.c),
53             SYS_FPATH => self.fpath(packet.b, unsafe { slice::from_raw_parts_mut(packet.c as *mut u8, packet.d) }),
54             SYS_FRENAME => if let Some(path) = unsafe { str_from_raw_parts(packet.c as *const u8, packet.d) } {
55                 self.frename(packet.b, path, packet.uid, packet.gid)
56             } else {
57                 Err(Error::new(EINVAL))
58             },
59             SYS_FSTAT => if packet.d >= mem::size_of::<Stat>() {
60                 self.fstat(packet.b, unsafe { &mut *(packet.c as *mut Stat) })
61             } else {
62                 Err(Error::new(EFAULT))
63             },
64             SYS_FSTATVFS => if packet.d >= mem::size_of::<StatVfs>() {
65                 self.fstatvfs(packet.b, unsafe { &mut *(packet.c as *mut StatVfs) })
66             } else {
67                 Err(Error::new(EFAULT))
68             },
69             SYS_FSYNC => self.fsync(packet.b),
70             SYS_FTRUNCATE => self.ftruncate(packet.b, packet.c),
71             SYS_FUTIMENS => if packet.d >= mem::size_of::<TimeSpec>() {
72                 self.futimens(packet.b, unsafe { slice::from_raw_parts(packet.c as *const TimeSpec, packet.d / mem::size_of::<TimeSpec>()) })
73             } else {
74                 Err(Error::new(EFAULT))
75             },
76             SYS_CLOSE => self.close(packet.b),
77             _ => Err(Error::new(ENOSYS))
78         };
79 
80         packet.a = Error::mux(res);
81     }
82 
83     /* Scheme operations */
84 
85     #[allow(unused_variables)]
open(&self, path: &str, flags: usize, uid: u32, gid: u32) -> Result<usize>86     fn open(&self, path: &str, flags: usize, uid: u32, gid: u32) -> Result<usize> {
87         Err(Error::new(ENOENT))
88     }
89 
90     #[allow(unused_variables)]
chmod(&self, path: &str, mode: u16, uid: u32, gid: u32) -> Result<usize>91     fn chmod(&self, path: &str, mode: u16, uid: u32, gid: u32) -> Result<usize> {
92         Err(Error::new(ENOENT))
93     }
94 
95     #[allow(unused_variables)]
rmdir(&self, path: &str, uid: u32, gid: u32) -> Result<usize>96     fn rmdir(&self, path: &str, uid: u32, gid: u32) -> Result<usize> {
97         Err(Error::new(ENOENT))
98     }
99 
100     #[allow(unused_variables)]
unlink(&self, path: &str, uid: u32, gid: u32) -> Result<usize>101     fn unlink(&self, path: &str, uid: u32, gid: u32) -> Result<usize> {
102         Err(Error::new(ENOENT))
103     }
104 
105     /* Resource operations */
106     #[allow(unused_variables)]
dup(&self, old_id: usize, buf: &[u8]) -> Result<usize>107     fn dup(&self, old_id: usize, buf: &[u8]) -> Result<usize> {
108         Err(Error::new(EBADF))
109     }
110 
111     #[allow(unused_variables)]
read(&self, id: usize, buf: &mut [u8]) -> Result<usize>112     fn read(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
113         Err(Error::new(EBADF))
114     }
115 
116     #[allow(unused_variables)]
write(&self, id: usize, buf: &[u8]) -> Result<usize>117     fn write(&self, id: usize, buf: &[u8]) -> Result<usize> {
118         Err(Error::new(EBADF))
119     }
120 
121     #[allow(unused_variables)]
seek(&self, id: usize, pos: isize, whence: usize) -> Result<isize>122     fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<isize> {
123         Err(Error::new(EBADF))
124     }
125 
126     #[allow(unused_variables)]
fchmod(&self, id: usize, mode: u16) -> Result<usize>127     fn fchmod(&self, id: usize, mode: u16) -> Result<usize> {
128         Err(Error::new(EBADF))
129     }
130 
131     #[allow(unused_variables)]
fchown(&self, id: usize, uid: u32, gid: u32) -> Result<usize>132     fn fchown(&self, id: usize, uid: u32, gid: u32) -> Result<usize> {
133         Err(Error::new(EBADF))
134     }
135 
136     #[allow(unused_variables)]
fcntl(&self, id: usize, cmd: usize, arg: usize) -> Result<usize>137     fn fcntl(&self, id: usize, cmd: usize, arg: usize) -> Result<usize> {
138         Err(Error::new(EBADF))
139     }
140 
141     #[allow(unused_variables)]
fevent(&self, id: usize, flags: EventFlags) -> Result<EventFlags>142     fn fevent(&self, id: usize, flags: EventFlags) -> Result<EventFlags> {
143         Err(Error::new(EBADF))
144     }
145 
146     #[allow(unused_variables)]
fmap_old(&self, id: usize, map: &OldMap) -> Result<usize>147     fn fmap_old(&self, id: usize, map: &OldMap) -> Result<usize> {
148         Err(Error::new(EBADF))
149     }
150     #[allow(unused_variables)]
fmap(&self, id: usize, map: &Map) -> Result<usize>151     fn fmap(&self, id: usize, map: &Map) -> Result<usize> {
152         if map.flags.contains(MapFlags::MAP_FIXED) {
153             return Err(Error::new(EINVAL));
154         }
155         self.fmap_old(id, &OldMap {
156             offset: map.offset,
157             size: map.size,
158             flags: map.flags,
159         })
160     }
161 
162     #[allow(unused_variables)]
funmap_old(&self, address: usize) -> Result<usize>163     fn funmap_old(&self, address: usize) -> Result<usize> {
164         Ok(0)
165     }
166 
167     #[allow(unused_variables)]
funmap(&self, address: usize, length: usize) -> Result<usize>168     fn funmap(&self, address: usize, length: usize) -> Result<usize> {
169         Ok(0)
170     }
171 
172     #[allow(unused_variables)]
fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize>173     fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
174         Err(Error::new(EBADF))
175     }
176 
177     #[allow(unused_variables)]
frename(&self, id: usize, path: &str, uid: u32, gid: u32) -> Result<usize>178     fn frename(&self, id: usize, path: &str, uid: u32, gid: u32) -> Result<usize> {
179         Err(Error::new(EBADF))
180     }
181 
182     #[allow(unused_variables)]
fstat(&self, id: usize, stat: &mut Stat) -> Result<usize>183     fn fstat(&self, id: usize, stat: &mut Stat) -> Result<usize> {
184         Err(Error::new(EBADF))
185     }
186 
187     #[allow(unused_variables)]
fstatvfs(&self, id: usize, stat: &mut StatVfs) -> Result<usize>188     fn fstatvfs(&self, id: usize, stat: &mut StatVfs) -> Result<usize> {
189         Err(Error::new(EBADF))
190     }
191 
192     #[allow(unused_variables)]
fsync(&self, id: usize) -> Result<usize>193     fn fsync(&self, id: usize) -> Result<usize> {
194         Err(Error::new(EBADF))
195     }
196 
197     #[allow(unused_variables)]
ftruncate(&self, id: usize, len: usize) -> Result<usize>198     fn ftruncate(&self, id: usize, len: usize) -> Result<usize> {
199         Err(Error::new(EBADF))
200     }
201 
202     #[allow(unused_variables)]
futimens(&self, id: usize, times: &[TimeSpec]) -> Result<usize>203     fn futimens(&self, id: usize, times: &[TimeSpec]) -> Result<usize> {
204         Err(Error::new(EBADF))
205     }
206 
207     #[allow(unused_variables)]
close(&self, id: usize) -> Result<usize>208     fn close(&self, id: usize) -> Result<usize> {
209         Err(Error::new(EBADF))
210     }
211 }
212