{-# LANGUAGE CPP #-}
module System.IO.HVFS.Utils (recurseDir,
recurseDirStat,
recursiveRemove,
lsl,
SystemFS(..)
)
where
import System.IO.HVFS
import System.Time.Utils
import System.IO.PlafCompat
import Text.Printf
import System.Time
import System.Locale
import System.IO.Unsafe
import System.FilePath ((</>), pathSeparator)
recurseDir :: HVFS a => a -> FilePath -> IO [FilePath]
recurseDir fs x = recurseDirStat fs x >>= return . map fst
recurseDirStat :: HVFS a => a -> FilePath -> IO [(FilePath, HVFSStatEncap)]
recurseDirStat h fn =
do fs <- vGetSymbolicLinkStatus h fn
if withStat fs vIsDirectory
then do
dirc <- vGetDirectoryContents h fn
let contents = map ((++) (fn ++ [pathSeparator])) $
filter (\x -> x /= "." && x /= "..") dirc
subdirs <- unsafeInterleaveIO $ mapM (recurseDirStat h) contents
return $ (concat subdirs) ++ [(fn, fs)]
else return [(fn, fs)]
recursiveRemove :: HVFS a => a -> FilePath -> IO ()
recursiveRemove h fn =
recurseDirStat h fn >>= (mapM_ $
\(fn, fs) -> if withStat fs vIsDirectory
then vRemoveDirectory h fn
else vRemoveFile h fn
)
lsl :: HVFS a => a -> FilePath -> IO String
lsl fs fp =
let showmodes mode =
let i m = (intersectFileModes mode m /= 0)
in
(if i ownerReadMode then 'r' else '-') :
(if i ownerWriteMode then 'w' else '-') :
(if i setUserIDMode then 's' else
if i ownerExecuteMode then 'x' else '-') :
(if i groupReadMode then 'r' else '-') :
(if i groupWriteMode then 'w' else '-') :
(if i setGroupIDMode then 's' else
if i groupExecuteMode then 'x' else '-') :
(if i otherReadMode then 'r' else '-') :
(if i otherWriteMode then 'w' else '-') :
(if i otherExecuteMode then 'x' else '-') : []
showentry origdir fh (state, fp) =
case state of
HVFSStatEncap se ->
let typechar =
if vIsDirectory se then 'd'
else if vIsSymbolicLink se then 'l'
else if vIsBlockDevice se then 'b'
else if vIsCharacterDevice se then 'c'
else if vIsSocket se then 's'
else if vIsNamedPipe se then 's'
else '-'
clocktime = epochToClockTime (vModificationTime se)
datestr c= formatCalendarTime defaultTimeLocale "%b %e %Y"
c
in do c <- toCalendarTime clocktime
linkstr <- case vIsSymbolicLink se of
False -> return ""
True -> do sl <- vReadSymbolicLink fh
(origdir </> fp)
return $ " -> " ++ sl
return $ printf "%c%s 1 %-8d %-8d %-9d %s %s%s"
typechar
(showmodes (vFileMode se))
(toInteger $ vFileOwner se)
(toInteger $ vFileGroup se)
(toInteger $ vFileSize se)
(datestr c)
fp
linkstr
in do c <- vGetDirectoryContents fs fp
pairs <- mapM (\x -> do ss <- vGetSymbolicLinkStatus fs (fp </> x)
return (ss, x)
) c
linedata <- mapM (showentry fp fs) pairs
return $ unlines $ ["total 1"] ++ linedata