Directory

-- | Directory Functions
-- <http://www.altocumulus.org/haskell98-report-html/directory.html>
module Directory(
       Permissions(..),
       createDirectory, removeDirectory, removeFile,
       renameDirectory, renameFile, getDirectoryContents,
       getCurrentDirectory, -- setCurrentDirectory,
       doesDirectoryExist, doesFileExist,
       getPermissions, -- setPermissions,
       getModificationTime ) where

import MonadicIO0
import IO(isDoesNotExistError)
import Time(ClockTime(..))
import PreludeIO(ioeAddPath)

data Permissions
  = Permissions { readable, writable, executable, searchable :: Bool }
  deriving ( Eq, Ord, Read, Show )

createDirectory new     = primCreateDirectory new `ioeAddPath` new
renameDirectory old new = primRenameFile old new
renameFile      old new = primRenameFile old new
removeFile      old     = primRemoveFile old `ioeAddPath` old
removeDirectory old     = primRemoveDirectory old `ioeAddPath` old

getDirectoryContents = primGetDirectoryContents
getCurrentDirectory = primGetCurrentDirectory

--foreign import setCurrentDirectory  :: FilePath -> IO () -- !!!
--foreign import setPermissions :: FilePath -> Permissions -> IO () -- !!!

getModificationTime path = ClockTime <$> primGetModificationTime path

getPermissions path = fmap convert (primGetFileMode path)
  where
    convert mode = Permissions r w (e && not d) (e && d)
      where
        d = isDirectory mode
        r = odd (mode `quot` 0o400)
	w = odd (mode `quot` 0o200)
	e = odd (mode `quot` 0o100)

isDirectory mode = mode `quot` 0o10000 `rem` 16 == 4
isRegular   mode = mode `quot` 0o10000 `rem` 16 == 0o10

doesDirectoryExist = doesItExist isDirectory
doesFileExist = doesItExist isRegular

doesItExist isTy path =
  catch (fmap isTy (primGetFileMode path))
        (\e->if isDoesNotExistError e then return False else ioError e)
  `ioeAddPath` path