{-# LINE 1 "System/Linux/Mount.hsc" #-}
{- |This module provides an interface to the system mount and umount functions. -}
{-# LINE 2 "System/Linux/Mount.hsc" #-}


module System.Linux.Mount
    (
    -- * Bindings to system functions
     mount
    , umount
    , umountWith
    , forceUmount

    -- *MountFlag
    , MountFlag
    -- **Constructors
    , mntRdonly
    , mntNosuid
    , mntNodev
    , mntNoexec
    , mntSynchronous
    , mntRemount
    , mntMandlock
    , mntDirsync
    , mntNoatime
    , mntNodiratime
    , mntBind
    , mntMove
    , mntRec
    , mntSilent
    , mntPosixacl
    , mntUnbindable
    , mntPrivate
    , mntSlave
    , mntShared
    , mntRelatime
    , mntKernmount
    , mntIVersion
    , mntStrictatime
    , mntActive
    , mntNouser

     -- * DriverData
    , DriverData
    -- **Constructors
    , noData

   -- *UmountFlag
    , UmountFlag
    -- **Constructors
    , umntForce
    , umntDetach
    , umntExpire
    , umntNofollow

    ) where


{-# LINE 57 "System/Linux/Mount.hsc" #-}

import Data.Bits
import Foreign
import Foreign.C
import Foreign.Marshal.Alloc

-- | Mounts a filesystem.
mount :: String        -- ^ device file
      -> FilePath      -- ^ mount point
      -> String        -- ^ filesystem type
      -> [MountFlag]   -- ^ list of mount options
      -> DriverData    -- ^ driver specific options
      -> IO ()
mount dev dir typ xs (DriverData ptr) = throwErrnoIfMinus1_ "mount" $ 
                                        do
                                          cdev <- newCString dev
                                          cdir <- newCString dir
                                          ctype <- newCString typ
                                          ret <- c_mount cdev
                                                 cdir
                                                 ctype
                                                 (genMountFlag xs)
                                                 ptr
                                          free cdev
                                          free cdir
                                          free ctype
                                          return ret

foreign import ccall unsafe "mount"
  c_mount :: Ptr CChar -> Ptr CChar -> Ptr CChar -> CULong -> Ptr a -> IO CInt

-- | Umounts a filesystem.
umount :: String -- ^ mount point
       -> IO ()
umount str = throwErrnoIfMinus1_ "umount"
             (withCString str (\cstr -> (c_umount cstr)))

foreign import ccall unsafe "umount"
  c_umount :: Ptr CChar -> IO CInt

-- | Umounts a filesystem using specific umount options.
umountWith :: UmountFlag -- ^ umount options
           -> String     -- ^ mount point
           -> IO ()
umountWith flag str = genUmount2 flag str "umountWith"

-- |Forces the filesystem umount (@forceUmount str = 'umountWith' 'umntForce' str@).
forceUmount :: String -- ^ mount point
            -> IO ()
forceUmount str = genUmount2 umntForce str "forceUmount"

genUmount2 (UmountFlag flag) str errmsg = throwErrnoIfMinus1_ errmsg
                                          (withCString str (\cstr -> c_umount2 cstr flag))

foreign import ccall unsafe "umount2"
  c_umount2 :: Ptr CChar -> CInt -> IO CInt

-- |MountFlag specifies the filesystem independent options to be used
-- when mounting a filesystem
newtype MountFlag = MountFlag CULong

mntNoflag = MountFlag 0




-- |DriverData specifies the filesystem dependent options to be used
-- when mounting a filesystem; the content of DriverData is passed
-- directly to the filesystem driver.
newtype DriverData = DriverData (Ptr ())

noData :: DriverData
noData = DriverData nullPtr

combine (MountFlag a) (MountFlag b) = MountFlag (a .|. b)
getInt (MountFlag a) = a

genMountFlag flags = getInt $ foldl combine (MountFlag 0) flags

-- |UmountFlag specifies the filesystem independent options to be used
-- when umounting a filesystem
newtype UmountFlag = UmountFlag CInt

umntForce :: UmountFlag
umntForce = UmountFlag 1
umntDetach :: UmountFlag
umntDetach = UmountFlag 2
umntExpire :: UmountFlag
umntExpire = UmountFlag 4
umntNofollow :: UmountFlag
umntNofollow = UmountFlag 8

{-# LINE 141 "System/Linux/Mount.hsc" #-}

mntRdonly :: MountFlag
mntRdonly = MountFlag 1
mntNosuid :: MountFlag
mntNosuid = MountFlag 2
mntNodev :: MountFlag
mntNodev = MountFlag 4
mntNoexec :: MountFlag
mntNoexec = MountFlag 8
mntSynchronous :: MountFlag
mntSynchronous = MountFlag 16
mntRemount :: MountFlag
mntRemount = MountFlag 32
mntMandlock :: MountFlag
mntMandlock = MountFlag 64
mntDirsync :: MountFlag
mntDirsync = MountFlag 128
mntNoatime :: MountFlag
mntNoatime = MountFlag 1024
mntNodiratime :: MountFlag
mntNodiratime = MountFlag 2048
mntBind :: MountFlag
mntBind = MountFlag 4096
mntMove :: MountFlag
mntMove = MountFlag 8192
mntRec :: MountFlag
mntRec = MountFlag 16384
mntSilent :: MountFlag
mntSilent = MountFlag 32768
mntPosixacl :: MountFlag
mntPosixacl = MountFlag 65536
mntUnbindable :: MountFlag
mntUnbindable = MountFlag 131072
mntPrivate :: MountFlag
mntPrivate = MountFlag 262144
mntSlave :: MountFlag
mntSlave = MountFlag 524288
mntShared :: MountFlag
mntShared = MountFlag 1048576
mntRelatime :: MountFlag
mntRelatime = MountFlag 2097152
mntKernmount :: MountFlag
mntKernmount = MountFlag 4194304
mntIVersion :: MountFlag
mntIVersion = MountFlag 8388608
mntStrictatime :: MountFlag
mntStrictatime = MountFlag 16777216
mntActive :: MountFlag
mntActive = MountFlag 1073741824
mntNouser :: MountFlag
mntNouser = MountFlag (-2147483648)

{-# LINE 143 "System/Linux/Mount.hsc" #-}