{-# 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.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 :: Word16 -> NineFile m -> Word8 -> Nine m ()
checkPerms Word16
tag NineFile m
f Word8
want = do
Stat
s <- Word16 -> NineFile m -> Nine m Stat
forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Stat
getStat Word16
tag NineFile m
f
Word32 -> Word8 -> Nine m ()
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' :: Word32 -> Word8 -> Nine m ()
checkPerms' Word32
have Word8
want = do
let checkRead :: Nine m ()
checkRead = Bool -> Nine m () -> Nine m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Word32 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word32
have Int
2) (Nine m () -> Nine m ()) -> Nine m () -> Nine m ()
forall a b. (a -> b) -> a -> b
$ NineError -> Nine m ()
forall a e. Exception e => e -> a
throw NineError
EPermissionDenied
let checkWrite :: Nine m ()
checkWrite = Bool -> Nine m () -> Nine m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Word32 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word32
have Int
1) (Nine m () -> Nine m ()) -> Nine m () -> Nine m ()
forall a b. (a -> b) -> a -> b
$ NineError -> Nine m ()
forall a e. Exception e => e -> a
throw NineError
EPermissionDenied
let checkExec :: Nine m ()
checkExec = Bool -> Nine m () -> Nine m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Word32 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word32
have Int
0) (Nine m () -> Nine m ()) -> Nine m () -> Nine m ()
forall a b. (a -> b) -> a -> b
$ NineError -> Nine m ()
forall a e. Exception e => e -> a
throw NineError
EPermissionDenied
Bool -> Nine m () -> Nine m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
want Int
4) (Nine m () -> Nine m ()) -> Nine m () -> Nine m ()
forall a b. (a -> b) -> a -> b
$ do
Nine m ()
checkWrite
NineError -> Nine m ()
forall a e. Exception e => e -> a
throw (NineError -> Nine m ()) -> NineError -> Nine m ()
forall a b. (a -> b) -> a -> b
$ String -> NineError
ENotImplemented String
"OTRUNC"
Bool -> Nine m () -> Nine m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word8
want Int
6) (Nine m () -> Nine m ()) -> Nine m () -> Nine m ()
forall a b. (a -> b) -> a -> b
$ do
NineError -> Nine m ()
forall a e. Exception e => e -> a
throw (NineError -> Nine m ()) -> NineError -> Nine m ()
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 Nine m () -> Nine m () -> Nine m ()
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 = Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Word8) -> Word32 -> Word8
forall a b. (a -> b) -> a -> b
$ Word32 -> Int -> Word32
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 :: Word16 -> NineFile m -> Nine m Qid
makeQid Word16
t NineFile m
x = do
Stat
s <- Word16 -> NineFile m -> Nine m Stat
forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Stat
getStat Word16
t NineFile m
x
Qid -> Nine m Qid
forall (m :: * -> *) a. Monad m => a -> m a
return (Qid -> Nine m Qid) -> Qid -> Nine m Qid
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 :: Msg -> Nine m [Msg]
rversion (Msg Tag
_ Word16
t (Tversion Word32
s String
v)) = do
let ver :: NineVersion
ver = String -> NineVersion
readVersion String
v
(NineState m -> NineState m)
-> MState (NineState m) (ReaderT (Config m) IO) ()
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 })
[Msg] -> Nine m [Msg]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Msg] -> Nine m [Msg]) -> [Msg] -> Nine m [Msg]
forall a b. (a -> b) -> a -> b
$ Msg -> [Msg]
forall (m :: * -> *) a. Monad m => a -> m a
return (Msg -> [Msg]) -> Msg -> [Msg]
forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRversion Word16
t (VarMsg -> Msg) -> VarMsg -> Msg
forall a b. (a -> b) -> a -> b
$ Word32 -> String -> VarMsg
Rversion Word32
s (String -> VarMsg) -> String -> VarMsg
forall a b. (a -> b) -> a -> b
$ NineVersion -> String
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 <- (Config m -> NineFile m)
-> MState (NineState m) (ReaderT (Config m) IO) (NineFile m)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks Config m -> NineFile m
forall (m :: * -> *). Config m -> NineFile m
root
Word32 -> NineFile m -> Nine m ()
forall (m :: * -> *). Word32 -> NineFile m -> Nine m ()
insert Word32
fid NineFile m
root
Qid
q <- Word16 -> NineFile m -> Nine m Qid
forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Qid
makeQid Word16
t NineFile m
root
m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall (m :: * -> *) a. Monad m => a -> m a
return (m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg))
-> m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall a b. (a -> b) -> a -> b
$ Msg -> m Msg
forall (m :: * -> *) a. Monad m => a -> m a
return (Msg -> m Msg) -> Msg -> m Msg
forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRattach Word16
t (VarMsg -> Msg) -> VarMsg -> Msg
forall a b. (a -> b) -> a -> b
$ Qid -> VarMsg
Rattach Qid
q
desc :: (Monad m, EmbedIO m) => NineFile m -> String -> m (NineFile m)
desc :: NineFile m -> String -> m (NineFile m)
desc NineFile m
f String
".." = do
Maybe (NineFile m)
mp <- NineFile m -> m (Maybe (NineFile m))
forall (m :: * -> *). NineFile m -> m (Maybe (NineFile m))
parent NineFile m
f
NineFile m -> m (NineFile m)
forall (m :: * -> *) a. Monad m => a -> m a
return (NineFile m -> m (NineFile m)) -> NineFile m -> m (NineFile m)
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 = NineFile m -> String -> m (NineFile m)
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 :: [Qid]
-> Word16 -> [String] -> NineFile m -> Nine m (NineFile m, [Qid])
walk [Qid]
qs Word16
t [] NineFile m
f = (NineFile m, [Qid]) -> Nine m (NineFile m, [Qid])
forall (m :: * -> *) a. Monad m => a -> m a
return (NineFile m
f, [Qid]
qs)
walk [Qid]
qs Word16
t (String
x:[String]
xs) (RegularFile {}) = NineError -> Nine m (NineFile m, [Qid])
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 <- Word16
-> m (NineFile m)
-> MState (NineState m) (ReaderT (Config m) IO) (NineFile m)
forall (m :: * -> *) a.
EmbedIO m =>
Word16 -> m a -> MState (NineState m) (ReaderT (Config m) IO) a
call Word16
t (m (NineFile m)
-> MState (NineState m) (ReaderT (Config m) IO) (NineFile m))
-> m (NineFile m)
-> MState (NineState m) (ReaderT (Config m) IO) (NineFile m)
forall a b. (a -> b) -> a -> b
$ NineFile m -> String -> m (NineFile m)
forall (m :: * -> *).
(Monad m, EmbedIO m) =>
NineFile m -> String -> m (NineFile m)
desc NineFile m
d String
x
Qid
q <- Word16 -> NineFile m -> Nine m Qid
forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Qid
makeQid Word16
t NineFile m
f
[Qid]
-> Word16 -> [String] -> NineFile m -> Nine m (NineFile m, [Qid])
forall (m :: * -> *).
(Monad m, EmbedIO m) =>
[Qid]
-> Word16 -> [String] -> NineFile m -> Nine m (NineFile m, [Qid])
walk (Qid
qQid -> [Qid] -> [Qid]
forall 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' :: Word16 -> [String] -> NineFile m -> Nine m (NineFile m, [Qid])
walk' = [Qid]
-> Word16 -> [String] -> NineFile m -> Nine m (NineFile m, [Qid])
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 <- Word32 -> Nine m (NineFile m)
forall (m :: * -> *). Word32 -> Nine m (NineFile m)
lookup Word32
fid
(NineFile m
nf, [Qid]
qs) <- Word16 -> [String] -> NineFile m -> Nine m (NineFile m, [Qid])
forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> [String] -> NineFile m -> Nine m (NineFile m, [Qid])
walk' Word16
t [String]
path NineFile m
f
Word32 -> NineFile m -> Nine m ()
forall (m :: * -> *). Word32 -> NineFile m -> Nine m ()
insert Word32
newfid NineFile m
nf
m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall (m :: * -> *) a. Monad m => a -> m a
return (m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg))
-> m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall a b. (a -> b) -> a -> b
$ Msg -> m Msg
forall (m :: * -> *) a. Monad m => a -> m a
return (Msg -> m Msg) -> Msg -> m Msg
forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRwalk Word16
t (VarMsg -> Msg) -> VarMsg -> Msg
forall a b. (a -> b) -> a -> b
$ [Qid] -> VarMsg
Rwalk ([Qid] -> VarMsg) -> [Qid] -> VarMsg
forall a b. (a -> b) -> a -> b
$ [Qid]
qs
getStat :: (Monad m, EmbedIO m) => Word16 -> NineFile m -> Nine m Stat
getStat :: Word16 -> NineFile m -> Nine m Stat
getStat Word16
t NineFile m
f = do
let fixDirBit :: Word32 -> Word32
fixDirBit = (case NineFile m
f of
(RegularFile {}) -> (Word32 -> Int -> Word32) -> Int -> Word32 -> Word32
forall a b c. (a -> b -> c) -> b -> a -> c
flip Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
clearBit Int
31
(Directory {}) -> (Word32 -> Int -> Word32) -> Int -> Word32 -> Word32
forall a b c. (a -> b -> c) -> b -> a -> c
flip Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
setBit Int
31
)
Stat
s <- Word16 -> m Stat -> Nine m Stat
forall (m :: * -> *) a.
EmbedIO m =>
Word16 -> m a -> MState (NineState m) (ReaderT (Config m) IO) a
call Word16
t (m Stat -> Nine m Stat) -> m Stat -> Nine m Stat
forall a b. (a -> b) -> a -> b
$ NineFile m -> m Stat
forall (m :: * -> *). NineFile m -> m Stat
stat NineFile m
f
Stat -> Nine m Stat
forall (m :: * -> *) a. Monad m => a -> m a
return Stat
s { st_mode :: Word32
st_mode = Word32 -> Word32
fixDirBit (Word32 -> Word32) -> Word32 -> Word32
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 <- Word32 -> Nine m (NineFile m)
forall (m :: * -> *). Word32 -> Nine m (NineFile m)
lookup Word32
fid
case NineFile m
f of
RegularFile {} -> do
Stat
s <- Word16 -> NineFile m -> Nine m Stat
forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Stat
getStat Word16
t NineFile m
f
m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall (m :: * -> *) a. Monad m => a -> m a
return (m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg))
-> m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall a b. (a -> b) -> a -> b
$ Msg -> m Msg
forall (m :: * -> *) a. Monad m => a -> m a
return (Msg -> m Msg) -> Msg -> m Msg
forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRstat Word16
t (VarMsg -> Msg) -> VarMsg -> Msg
forall a b. (a -> b) -> a -> b
$ [Stat] -> VarMsg
Rstat ([Stat] -> VarMsg) -> [Stat] -> VarMsg
forall a b. (a -> b) -> a -> b
$ [Stat
s]
Directory {} -> do
Stat
mys <- Word16 -> NineFile m -> Nine m Stat
forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Stat
getStat Word16
t NineFile m
f
m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall (m :: * -> *) a. Monad m => a -> m a
return (m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg))
-> m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall a b. (a -> b) -> a -> b
$ Msg -> m Msg
forall (m :: * -> *) a. Monad m => a -> m a
return (Msg -> m Msg) -> Msg -> m Msg
forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRstat Word16
t (VarMsg -> Msg) -> VarMsg -> Msg
forall a b. (a -> b) -> a -> b
$ [Stat] -> VarMsg
Rstat ([Stat] -> VarMsg) -> [Stat] -> VarMsg
forall a b. (a -> b) -> a -> b
$ Stat -> [Stat]
forall (m :: * -> *) a. Monad m => a -> m a
return (Stat -> [Stat]) -> Stat -> [Stat]
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
Word32 -> Nine m ()
forall (m :: * -> *). Word32 -> Nine m ()
delete Word32
fid
m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall (m :: * -> *) a. Monad m => a -> m a
return (m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg))
-> m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall a b. (a -> b) -> a -> b
$ Msg -> m Msg
forall (m :: * -> *) a. Monad m => a -> m a
return (Msg -> m Msg) -> Msg -> m Msg
forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRclunk Word16
t (VarMsg -> Msg) -> VarMsg -> Msg
forall a b. (a -> b) -> a -> b
$ VarMsg
Rclunk
rauth :: Msg -> a
rauth (Msg {}) = do
NineError -> a
forall a e. Exception e => e -> a
throw NineError
ENoAuthRequired
open :: (Monad m, EmbedIO m) => Word16 -> NineFile m -> Nine m Qid
open :: Word16 -> NineFile m -> Nine m Qid
open Word16
t NineFile m
f = do
Word16 -> NineFile m -> Nine m Qid
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 <- Word32 -> Nine m (NineFile m)
forall (m :: * -> *). Word32 -> Nine m (NineFile m)
lookup Word32
fid
Word16 -> NineFile m -> Word8 -> Nine m ()
forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Word8 -> Nine m ()
checkPerms Word16
t NineFile m
f Word8
mode
Qid
qid <- Word16 -> NineFile m -> Nine m Qid
forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Qid
open Word16
t NineFile m
f
Word32
iou <- Nine m Word32
forall (m :: * -> *). Nine m Word32
iounit
m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall (m :: * -> *) a. Monad m => a -> m a
return (m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg))
-> m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall a b. (a -> b) -> a -> b
$ Msg -> m Msg
forall (m :: * -> *) a. Monad m => a -> m a
return (Msg -> m Msg) -> Msg -> m Msg
forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRopen Word16
t (VarMsg -> Msg) -> VarMsg -> Msg
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 <- Word32 -> Nine m (NineFile m)
forall (m :: * -> *). Word32 -> Nine m (NineFile m)
lookup Word32
fid
case NineFile m
f of
RegularFile {} -> NineError -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall a e. Exception e => e -> a
throw NineError
ENotADir
Directory {} -> do
NineFile m
nf <- Word16 -> m (NineFile m) -> Nine m (NineFile m)
forall (m :: * -> *) a.
EmbedIO m =>
Word16 -> m a -> MState (NineState m) (ReaderT (Config m) IO) a
call Word16
t (m (NineFile m) -> Nine m (NineFile m))
-> m (NineFile m) -> Nine m (NineFile m)
forall a b. (a -> b) -> a -> b
$ (NineFile m -> String -> Word32 -> m (NineFile m)
forall (m :: * -> *).
NineFile m -> String -> Word32 -> m (NineFile m)
create NineFile m
f) String
name Word32
perm
Word32 -> NineFile m -> Nine m ()
forall (m :: * -> *). Word32 -> NineFile m -> Nine m ()
insert Word32
fid NineFile m
nf
Qid
qid <- Word16 -> NineFile m -> Nine m Qid
forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Qid
open Word16
t NineFile m
f
Word32
iou <- Nine m Word32
forall (m :: * -> *). Nine m Word32
iounit
m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall (m :: * -> *) a. Monad m => a -> m a
return (m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg))
-> m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall a b. (a -> b) -> a -> b
$ Msg -> m Msg
forall (m :: * -> *) a. Monad m => a -> m a
return (Msg -> m Msg) -> Msg -> m Msg
forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRcreate Word16
t (VarMsg -> Msg) -> VarMsg -> Msg
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 :: Msg -> Nine m [Msg]
rread (Msg Tag
_ Word16
t (Tread Word32
fid Word64
offset Word32
count)) = do
NineFile m
f <- Word32 -> Nine m (NineFile m)
forall (m :: * -> *). Word32 -> Nine m (NineFile m)
lookup Word32
fid
Word32
u <- Nine m Word32
forall (m :: * -> *). Nine m Word32
iounit
Word16 -> NineFile m -> Word8 -> Nine m ()
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 [ByteString] -> Bool
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 ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: ByteString -> Int64 -> [ByteString]
splitMsg' ByteString
b Int64
s
case NineFile m
f of
RegularFile {} -> do
ByteString
d <- Word16
-> m ByteString
-> MState (NineState m) (ReaderT (Config m) IO) ByteString
forall (m :: * -> *) a.
EmbedIO m =>
Word16 -> m a -> MState (NineState m) (ReaderT (Config m) IO) a
call Word16
t (m ByteString
-> MState (NineState m) (ReaderT (Config m) IO) ByteString)
-> m ByteString
-> MState (NineState m) (ReaderT (Config m) IO) ByteString
forall a b. (a -> b) -> a -> b
$ (NineFile m -> Word64 -> Word32 -> m ByteString
forall (m :: * -> *).
NineFile m -> Word64 -> Word32 -> m ByteString
read NineFile m
f) Word64
offset Word32
count
(ByteString -> MState (NineState m) (ReaderT (Config m) IO) Msg)
-> [ByteString] -> Nine m [Msg]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Msg -> MState (NineState m) (ReaderT (Config m) IO) Msg
forall (m :: * -> *) a. Monad m => a -> m a
return (Msg -> MState (NineState m) (ReaderT (Config m) IO) Msg)
-> (ByteString -> Msg)
-> ByteString
-> MState (NineState m) (ReaderT (Config m) IO) Msg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRread Word16
t (VarMsg -> Msg) -> (ByteString -> VarMsg) -> ByteString -> Msg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> VarMsg
Rread) ([ByteString] -> Nine m [Msg]) -> [ByteString] -> Nine m [Msg]
forall a b. (a -> b) -> a -> b
$ ByteString -> Int64 -> [ByteString]
splitMsg ByteString
d (Int64 -> [ByteString]) -> Int64 -> [ByteString]
forall a b. (a -> b) -> a -> b
$ Word32 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
u
Directory {} -> do
[NineFile m]
contents <- Word16
-> m [NineFile m]
-> MState (NineState m) (ReaderT (Config m) IO) [NineFile m]
forall (m :: * -> *) a.
EmbedIO m =>
Word16 -> m a -> MState (NineState m) (ReaderT (Config m) IO) a
call Word16
t (m [NineFile m]
-> MState (NineState m) (ReaderT (Config m) IO) [NineFile m])
-> m [NineFile m]
-> MState (NineState m) (ReaderT (Config m) IO) [NineFile m]
forall a b. (a -> b) -> a -> b
$ NineFile m -> m [NineFile m]
forall (m :: * -> *). NineFile m -> m [NineFile m]
getFiles NineFile m
f
[Stat]
s <- (NineFile m -> MState (NineState m) (ReaderT (Config m) IO) Stat)
-> [NineFile m]
-> MState (NineState m) (ReaderT (Config m) IO) [Stat]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Word16
-> NineFile m -> MState (NineState m) (ReaderT (Config m) IO) Stat
forall (m :: * -> *).
(Monad m, EmbedIO m) =>
Word16 -> NineFile m -> Nine m Stat
getStat Word16
t) ([NineFile m]
-> MState (NineState m) (ReaderT (Config m) IO) [Stat])
-> [NineFile m]
-> MState (NineState m) (ReaderT (Config m) IO) [Stat]
forall a b. (a -> b) -> a -> b
$ [NineFile m]
contents
let d :: ByteString
d = Put -> ByteString
runPut (Put -> ByteString) -> Put -> ByteString
forall a b. (a -> b) -> a -> b
$ (Stat -> Put) -> [Stat] -> Put
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Stat -> Put
forall a. Bin a => a -> Put
put [Stat]
s
(ByteString -> MState (NineState m) (ReaderT (Config m) IO) Msg)
-> [ByteString] -> Nine m [Msg]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Msg -> MState (NineState m) (ReaderT (Config m) IO) Msg
forall (m :: * -> *) a. Monad m => a -> m a
return (Msg -> MState (NineState m) (ReaderT (Config m) IO) Msg)
-> (ByteString -> Msg)
-> ByteString
-> MState (NineState m) (ReaderT (Config m) IO) Msg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRread Word16
t (VarMsg -> Msg) -> (ByteString -> VarMsg) -> ByteString -> Msg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> VarMsg
Rread) ([ByteString] -> Nine m [Msg]) -> [ByteString] -> Nine m [Msg]
forall a b. (a -> b) -> a -> b
$ ByteString -> Int64 -> [ByteString]
splitMsg (Int64 -> ByteString -> ByteString
B.drop (Word64 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
offset) ByteString
d) (Int64 -> [ByteString]) -> Int64 -> [ByteString]
forall a b. (a -> b) -> a -> b
$ Word32 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
u
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 <- Word32 -> Nine m (NineFile m)
forall (m :: * -> *). Word32 -> Nine m (NineFile m)
lookup Word32
fid
Word16 -> NineFile m -> Word8 -> Nine m ()
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 {} -> NineError -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall a e. Exception e => e -> a
throw NineError
EDir
RegularFile {} -> do
Word32
c <- Word16
-> m Word32 -> MState (NineState m) (ReaderT (Config m) IO) Word32
forall (m :: * -> *) a.
EmbedIO m =>
Word16 -> m a -> MState (NineState m) (ReaderT (Config m) IO) a
call Word16
t (m Word32 -> MState (NineState m) (ReaderT (Config m) IO) Word32)
-> m Word32 -> MState (NineState m) (ReaderT (Config m) IO) Word32
forall a b. (a -> b) -> a -> b
$ (NineFile m -> Word64 -> ByteString -> m Word32
forall (m :: * -> *).
NineFile m -> Word64 -> ByteString -> m Word32
write NineFile m
f) Word64
offset ByteString
d
m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall (m :: * -> *) a. Monad m => a -> m a
return (m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg))
-> m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall a b. (a -> b) -> a -> b
$ Msg -> m Msg
forall (m :: * -> *) a. Monad m => a -> m a
return (Msg -> m Msg) -> Msg -> m Msg
forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRwrite Word16
t (VarMsg -> Msg) -> VarMsg -> Msg
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
NineFile m
f <- Word32 -> Nine m (NineFile m)
forall (m :: * -> *). Word32 -> Nine m (NineFile m)
lookup Word32
fid
m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall (m :: * -> *) a. Monad m => a -> m a
return (m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg))
-> m Msg -> MState (NineState m) (ReaderT (Config m) IO) (m Msg)
forall a b. (a -> b) -> a -> b
$ Msg -> m Msg
forall (m :: * -> *) a. Monad m => a -> m a
return (Msg -> m Msg) -> Msg -> m Msg
forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRwstat Word16
t (VarMsg -> Msg) -> VarMsg -> Msg
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
NineFile m
f <- Word32 -> Nine m (NineFile m)
forall (m :: * -> *). Word32 -> Nine m (NineFile m)
lookup Word32
fid
NineError -> MState (NineState m) (ReaderT (Config m) IO) b
forall a e. Exception e => e -> a
throw (NineError -> MState (NineState m) (ReaderT (Config m) IO) b)
-> NineError -> MState (NineState m) (ReaderT (Config m) IO) b
forall a b. (a -> b) -> a -> b
$ String -> NineError
ENotImplemented String
"remove"
rflush :: Msg -> m (m Msg)
rflush (Msg Tag
_ Word16
t VarMsg
_) = m Msg -> m (m Msg)
forall (m :: * -> *) a. Monad m => a -> m a
return (m Msg -> m (m Msg)) -> m Msg -> m (m Msg)
forall a b. (a -> b) -> a -> b
$ Msg -> m Msg
forall (m :: * -> *) a. Monad m => a -> m a
return (Msg -> m Msg) -> Msg -> m Msg
forall a b. (a -> b) -> a -> b
$ Tag -> Word16 -> VarMsg -> Msg
Msg Tag
TRflush Word16
t (VarMsg -> Msg) -> VarMsg -> Msg
forall a b. (a -> b) -> a -> b
$ VarMsg
Rflush