{-# LANGUAGE OverloadedStrings, FlexibleContexts #-}

module Network.NineP.Internal.Msg
	( Config(..)
	, rversion
	, rattach
	, rwalk
	, rstat
	, rwstat
	, rclunk
	, rauth
	, ropen
	, rcreate
	, rread
	, rwrite
	, rremove
	, rflush
	) where

import Control.Concurrent.MState hiding (put)
import Control.Exception
import Control.Monad
import Control.Monad.EmbedIO
import Control.Monad.Reader
import Data.Binary.Put
import Data.Bits
import qualified Data.ByteString.Lazy as B
import Data.NineP
import Data.Map (Map)
import Data.Maybe
import Data.Word
import Prelude hiding (lookup, read)

import Network.NineP.Error
import Network.NineP.Internal.File
import Network.NineP.Internal.State

checkPerms :: (Monad m, EmbedIO m) => Word16 -> NineFile m -> Word8 -> Nine m ()
checkPerms :: forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Word8 -> Nine m ()
checkPerms Word16
tag NineFile m
f Word8
want = do
	Stat
s <- forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Stat
getStat Word16
tag NineFile m
f
	forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word32 -> Word8 -> Nine m ()
checkPerms' (Stat -> Word32
st_mode Stat
s) Word8
want

checkPerms' :: (Monad m, EmbedIO m) => Word32 -> Word8 -> Nine m ()
checkPerms' :: forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word32 -> Word8 -> Nine m ()
checkPerms' Word32
have Word8
want = do
	-- TODO stop presuming we are owners
	let checkRead :: Nine m ()
checkRead = forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (forall a. Bits a => a -> Int -> Bool
testBit Word32
have Int
2) forall a b. (a -> b) -> a -> b
$ forall a e. Exception e => e -> a
throw NineError
EPermissionDenied
	let checkWrite :: Nine m ()
checkWrite = forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (forall a. Bits a => a -> Int -> Bool
testBit Word32
have Int
1) forall a b. (a -> b) -> a -> b
$ forall a e. Exception e => e -> a
throw NineError
EPermissionDenied
	let checkExec :: Nine m ()
checkExec = forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (forall a. Bits a => a -> Int -> Bool
testBit Word32
have Int
0) forall a b. (a -> b) -> a -> b
$ forall a e. Exception e => e -> a
throw NineError
EPermissionDenied
	forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (forall a. Bits a => a -> Int -> Bool
testBit Word8
want Int
4) forall a b. (a -> b) -> a -> b
$ do
		Nine m ()
checkWrite
		forall a e. Exception e => e -> a
throw forall a b. (a -> b) -> a -> b
$ String -> NineError
ENotImplemented String
"OTRUNC"
	forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (forall a. Bits a => a -> Int -> Bool
testBit Word8
want Int
6) forall a b. (a -> b) -> a -> b
$ do
		forall a e. Exception e => e -> a
throw forall a b. (a -> b) -> a -> b
$ String -> NineError
ENotImplemented String
"ORCLOSE"
	case Word8
want of
		Word8
0 -> Nine m ()
checkRead
		Word8
1 -> Nine m ()
checkWrite
		Word8
2 -> Nine m ()
checkRead forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Nine m ()
checkWrite
		Word8
3 -> Nine m ()
checkExec

getQidTyp :: Stat -> Word8
getQidTyp :: Stat -> Word8
getQidTyp Stat
s = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall a. Bits a => a -> Int -> a
shift (Stat -> Word32
st_mode Stat
s) Int
24

makeQid :: (Monad m, EmbedIO m) => Word16 -> NineFile m -> Nine m Qid
makeQid :: forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Qid
makeQid Word16
t NineFile m
x = do
	Stat
s <- forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Stat
getStat Word16
t NineFile m
x
	forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Word8 -> Word32 -> Word64 -> Qid
Qid (Stat -> Word8
getQidTyp Stat
s) Word32
0 Word64
42

rversion :: Msg -> Nine m [Msg]
rversion :: forall (m :: * -> *). Msg -> Nine m [Msg]
rversion (Msg Tag
_ Word16
t (Tversion Word32
s String
v)) = do
	let ver :: NineVersion
ver = String -> NineVersion
readVersion String
v
	forall (m :: * -> *) t. MonadIO m => (t -> t) -> MState t m ()
modifyM_ (\NineState m
st -> NineState m
st { msize :: Word32
msize = Word32
s, protoVersion :: NineVersion
protoVersion = NineVersion
ver })
	-- FIXME clunk everything and abort all outstanding I/O
	forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRversion Word16
t forall a b. (a -> b) -> a -> b
$ Word32 -> String -> VarMsg
Rversion Word32
s forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show NineVersion
ver

rattach :: Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
rattach (Msg Tag
_ Word16
t (Tattach Word32
fid Word32
_ String
_ String
_)) = do
	NineFile m
root <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall (m :: * -> *). Config m -> NineFile m
root
	forall (m :: * -> *). Word32 -> NineFile m -> Nine m ()
insert Word32
fid NineFile m
root
	Qid
q <- forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Qid
makeQid Word16
t NineFile m
root
	forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRattach Word16
t forall a b. (a -> b) -> a -> b
$ Qid -> VarMsg
Rattach Qid
q 

desc :: (Monad m, EmbedIO m) => NineFile m -> String -> m (NineFile m)
desc :: forall (m :: * -> *).
(Monad m, EmbedIO m) =>
NineFile m -> String -> m (NineFile m)
desc NineFile m
f String
".." = do
	Maybe (NineFile m)
mp <- forall (m :: * -> *). NineFile m -> m (Maybe (NineFile m))
parent NineFile m
f
	forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ case Maybe (NineFile m)
mp of
		Just NineFile m
p -> NineFile m
p
		Maybe (NineFile m)
Nothing -> NineFile m
f
desc NineFile m
f String
s = forall (m :: * -> *). NineFile m -> String -> m (NineFile m)
descend NineFile m
f String
s

walk :: (Monad m, EmbedIO m) => [Qid] -> Word16 -> [String] -> NineFile m -> Nine m (NineFile m, [Qid])
walk :: forall (m :: * -> *).
(Monad m, EmbedIO m) =>
[Qid]
-> Word16 -> [String] -> NineFile m -> Nine m (NineFile m, [Qid])
walk [Qid]
qs Word16
t [] NineFile m
f = forall (m :: * -> *) a. Monad m => a -> m a
return (NineFile m
f, [Qid]
qs)
walk [Qid]
qs Word16
t (String
x:[String]
xs) (RegularFile {}) = forall a e. Exception e => e -> a
throw NineError
ENotADir
walk [Qid]
qs Word16
t (String
x:[String]
xs) d :: NineFile m
d@(Directory {}) = do
	NineFile m
f <- forall (m :: * -> *) a.
EmbedIO m =>
Word16 -> m a -> MState (NineState m) (ReaderT (Config m) IO) a
call Word16
t forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
(Monad m, EmbedIO m) =>
NineFile m -> String -> m (NineFile m)
desc NineFile m
d String
x
	Qid
q <- forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Qid
makeQid Word16
t NineFile m
f
	forall (m :: * -> *).
(Monad m, EmbedIO m) =>
[Qid]
-> Word16 -> [String] -> NineFile m -> Nine m (NineFile m, [Qid])
walk (Qid
qforall a. a -> [a] -> [a]
:[Qid]
qs) Word16
t [String]
xs NineFile m
f

walk' :: (Monad m, EmbedIO m) => Word16 -> [String] -> NineFile m -> Nine m (NineFile m, [Qid])
walk' :: forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> [String] -> NineFile m -> Nine m (NineFile m, [Qid])
walk' = forall (m :: * -> *).
(Monad m, EmbedIO m) =>
[Qid]
-> Word16 -> [String] -> NineFile m -> Nine m (NineFile m, [Qid])
walk []

rwalk :: Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
rwalk (Msg Tag
_ Word16
t (Twalk Word32
fid Word32
newfid [String]
path)) = do
	NineFile m
f <- forall (m :: * -> *). Word32 -> Nine m (NineFile m)
lookup Word32
fid
	(NineFile m
nf, [Qid]
qs) <- forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> [String] -> NineFile m -> Nine m (NineFile m, [Qid])
walk' Word16
t [String]
path NineFile m
f
	forall (m :: * -> *). Word32 -> NineFile m -> Nine m ()
insert Word32
newfid NineFile m
nf
	forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRwalk Word16
t forall a b. (a -> b) -> a -> b
$ [Qid] -> VarMsg
Rwalk forall a b. (a -> b) -> a -> b
$ [Qid]
qs

getStat :: (Monad m, EmbedIO m) => Word16 -> NineFile m -> Nine m Stat
getStat :: forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Stat
getStat Word16
t NineFile m
f = do
	let fixDirBit :: Word32 -> Word32
fixDirBit = (case NineFile m
f of
				(RegularFile {}) -> forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Bits a => a -> Int -> a
clearBit Int
31
				(Directory {}) -> forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Bits a => a -> Int -> a
setBit Int
31
			)
	Stat
s <- forall (m :: * -> *) a.
EmbedIO m =>
Word16 -> m a -> MState (NineState m) (ReaderT (Config m) IO) a
call Word16
t forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). NineFile m -> m Stat
stat NineFile m
f
	forall (m :: * -> *) a. Monad m => a -> m a
return Stat
s { st_mode :: Word32
st_mode = Word32 -> Word32
fixDirBit forall a b. (a -> b) -> a -> b
$ Stat -> Word32
st_mode Stat
s,
		st_qid :: Qid
st_qid = (Stat -> Qid
st_qid Stat
s) { qid_typ :: Word8
qid_typ = Stat -> Word8
getQidTyp Stat
s } }
	
rstat :: Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
rstat (Msg Tag
_ Word16
t (Tstat Word32
fid)) = do
	NineFile m
f <- forall (m :: * -> *). Word32 -> Nine m (NineFile m)
lookup Word32
fid
	case NineFile m
f of
		RegularFile {} -> do
			Stat
s <- forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Stat
getStat Word16
t NineFile m
f
			forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRstat Word16
t forall a b. (a -> b) -> a -> b
$ [Stat] -> VarMsg
Rstat forall a b. (a -> b) -> a -> b
$ [Stat
s]
		Directory {} -> do
			Stat
mys <- forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Stat
getStat Word16
t NineFile m
f
			forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRstat Word16
t forall a b. (a -> b) -> a -> b
$ [Stat] -> VarMsg
Rstat forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Stat
mys

rclunk :: Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
rclunk (Msg Tag
_ Word16
t (Tclunk Word32
fid)) = do
	forall (m :: * -> *). Word32 -> Nine m ()
delete Word32
fid
	forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRclunk Word16
t forall a b. (a -> b) -> a -> b
$ VarMsg
Rclunk

rauth :: Msg -> a
rauth (Msg {}) = do
	forall a e. Exception e => e -> a
throw NineError
ENoAuthRequired

open :: (Monad m, EmbedIO m) => Word16 -> NineFile m -> Nine m Qid
open :: forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Qid
open Word16
t NineFile m
f = do
	forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Qid
makeQid Word16
t NineFile m
f

ropen :: Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
ropen (Msg Tag
_ Word16
t (Topen Word32
fid Word8
mode)) = do
	NineFile m
f <- forall (m :: * -> *). Word32 -> Nine m (NineFile m)
lookup Word32
fid
	forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Word8 -> Nine m ()
checkPerms Word16
t NineFile m
f Word8
mode
	Qid
qid <- forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Qid
open Word16
t NineFile m
f
	Word32
iou <- forall (m :: * -> *). Nine m Word32
iounit
	forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRopen Word16
t forall a b. (a -> b) -> a -> b
$ Qid -> Word32 -> VarMsg
Ropen Qid
qid Word32
iou

rcreate :: Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
rcreate (Msg Tag
_ Word16
t (Tcreate Word32
fid String
name Word32
perm Word8
mode)) = do
	NineFile m
f <- forall (m :: * -> *). Word32 -> Nine m (NineFile m)
lookup Word32
fid
	-- TODO check permissions to create
	case NineFile m
f of
		RegularFile {} -> forall a e. Exception e => e -> a
throw NineError
ENotADir
		Directory {} -> do
			NineFile m
nf <- forall (m :: * -> *) a.
EmbedIO m =>
Word16 -> m a -> MState (NineState m) (ReaderT (Config m) IO) a
call Word16
t forall a b. (a -> b) -> a -> b
$ (forall (m :: * -> *).
NineFile m -> String -> Word32 -> m (NineFile m)
create NineFile m
f) String
name Word32
perm
			forall (m :: * -> *). Word32 -> NineFile m -> Nine m ()
insert Word32
fid NineFile m
nf
			Qid
qid <- forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Qid
open Word16
t NineFile m
f
			Word32
iou <- forall (m :: * -> *). Nine m Word32
iounit
			forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRcreate Word16
t forall a b. (a -> b) -> a -> b
$ Qid -> Word32 -> VarMsg
Rcreate Qid
qid Word32
iou

rread :: (Monad m, EmbedIO m) => Msg -> Nine m [Msg]
rread :: forall (m :: * -> *). (Monad m, EmbedIO m) => Msg -> Nine m [Msg]
rread (Msg Tag
_ Word16
t (Tread Word32
fid Word64
offset Word32
count)) = do
	NineFile m
f <- forall (m :: * -> *). Word32 -> Nine m (NineFile m)
lookup Word32
fid
	Word32
u <- forall (m :: * -> *). Nine m Word32
iounit
	forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Word8 -> Nine m ()
checkPerms Word16
t NineFile m
f Word8
0
	let	splitMsg :: ByteString -> Int64 -> [ByteString]
splitMsg ByteString
d Int64
s = let r :: [ByteString]
r = ByteString -> Int64 -> [ByteString]
splitMsg' ByteString
d Int64
s in if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ByteString]
r then [ByteString
B.empty] else [ByteString]
r
		splitMsg' :: ByteString -> Int64 -> [ByteString]
splitMsg' ByteString
d Int64
s = if ByteString -> Bool
B.null ByteString
d then [] else
			let (ByteString
a, ByteString
b) = Int64 -> ByteString -> (ByteString, ByteString)
B.splitAt Int64
s ByteString
d in ByteString
a forall a. a -> [a] -> [a]
: ByteString -> Int64 -> [ByteString]
splitMsg' ByteString
b Int64
s
	case NineFile m
f of
		RegularFile {} -> do
			ByteString
d <- forall (m :: * -> *) a.
EmbedIO m =>
Word16 -> m a -> MState (NineState m) (ReaderT (Config m) IO) a
call Word16
t forall a b. (a -> b) -> a -> b
$ (forall (m :: * -> *).
NineFile m -> Word64 -> Word32 -> m ByteString
read NineFile m
f) Word64
offset Word32
count
			forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRread Word16
t forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> VarMsg
Rread) forall a b. (a -> b) -> a -> b
$ ByteString -> Int64 -> [ByteString]
splitMsg ByteString
d forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
u
		Directory {} -> do
			[NineFile m]
contents <- forall (m :: * -> *) a.
EmbedIO m =>
Word16 -> m a -> MState (NineState m) (ReaderT (Config m) IO) a
call Word16
t forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *). NineFile m -> m [NineFile m]
getFiles NineFile m
f
			[Stat]
s <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Stat
getStat Word16
t) forall a b. (a -> b) -> a -> b
$ [NineFile m]
contents
			let d :: ByteString
d = Put -> ByteString
runPut forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall a. Bin a => a -> Put
put [Stat]
s
			forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRread Word16
t forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> VarMsg
Rread) forall a b. (a -> b) -> a -> b
$ ByteString -> Int64 -> [ByteString]
splitMsg (Int64 -> ByteString -> ByteString
B.drop (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
offset) ByteString
d) forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
u
		
--rwrite :: Msg -> Nine m [Msg]
rwrite :: Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
rwrite (Msg Tag
_ Word16
t (Twrite Word32
fid Word64
offset ByteString
d)) = do
	NineFile m
f <- forall (m :: * -> *). Word32 -> Nine m (NineFile m)
lookup Word32
fid
	forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Word8 -> Nine m ()
checkPerms Word16
t NineFile m
f Word8
1
	case NineFile m
f of
		Directory {} -> forall a e. Exception e => e -> a
throw NineError
EDir
		RegularFile {} -> do
			Word32
c <- forall (m :: * -> *) a.
EmbedIO m =>
Word16 -> m a -> MState (NineState m) (ReaderT (Config m) IO) a
call Word16
t forall a b. (a -> b) -> a -> b
$ (forall (m :: * -> *).
NineFile m -> Word64 -> ByteString -> m Word32
write NineFile m
f) Word64
offset ByteString
d
			forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRwrite Word16
t forall a b. (a -> b) -> a -> b
$ Word32 -> VarMsg
Rwrite Word32
c

rwstat :: Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
rwstat (Msg Tag
_ Word16
t (Twstat Word32
fid [Stat]
stat)) = do
	-- TODO check perms
	NineFile m
f <- forall (m :: * -> *). Word32 -> Nine m (NineFile m)
lookup Word32
fid
	-- TODO implement
	forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRwstat Word16
t forall a b. (a -> b) -> a -> b
$ VarMsg
Rwstat

rremove :: Msg -> MState (NineState m) (ReaderT (Config m) IO) b
rremove (Msg Tag
_ Word16
t (Tremove Word32
fid)) = do
	-- TODO check perms
	NineFile m
f <- forall (m :: * -> *). Word32 -> Nine m (NineFile m)
lookup Word32
fid
	forall a e. Exception e => e -> a
throw forall a b. (a -> b) -> a -> b
$ String -> NineError
ENotImplemented String
"remove"

-- TODO meaningful flush behaviour instead of pretending it works
rflush :: Msg -> m (m Msg)
rflush (Msg Tag
_ Word16
t VarMsg
_) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRflush Word16
t forall a b. (a -> b) -> a -> b
$ VarMsg
Rflush