aboutsummaryrefslogtreecommitdiff
path: root/Utility/FileMode.hs
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2012-04-21 14:06:36 -0400
committerGravatar Joey Hess <joey@kitenet.net>2012-04-21 15:36:52 -0400
commitb4a5e39ee62020380fc0dcf7aecaaf593d44dba5 (patch)
treea1568a517e886440a8321472a1aeac8cb517f6ea /Utility/FileMode.hs
parent10d3e9162624cec5ef60e175cbf33b62f1efe90b (diff)
Support git's core.sharedRepository configuration
This is incomplete, it does not honor it yet for hash directories and other annex bookkeeping files. Some of that is not needed for a bare repo; some of it may be.
Diffstat (limited to 'Utility/FileMode.hs')
-rw-r--r--Utility/FileMode.hs60
1 files changed, 50 insertions, 10 deletions
diff --git a/Utility/FileMode.hs b/Utility/FileMode.hs
index 4992690c6..98c7124c2 100644
--- a/Utility/FileMode.hs
+++ b/Utility/FileMode.hs
@@ -1,6 +1,6 @@
{- File mode utilities.
-
- - Copyright 2010 Joey Hess <joey@kitenet.net>
+ - Copyright 2010-2012 Joey Hess <joey@kitenet.net>
-
- Licensed under the GNU GPL version 3 or higher.
-}
@@ -9,16 +9,36 @@ module Utility.FileMode where
import Common
+import Control.Exception (bracket)
import System.Posix.Types
import Foreign (complement)
+combineModes :: [FileMode] -> FileMode
+combineModes [] = undefined
+combineModes [m] = m
+combineModes (m:ms) = foldl unionFileModes m ms
+
+{- Applies a conversion function to a file's mode. -}
modifyFileMode :: FilePath -> (FileMode -> FileMode) -> IO ()
modifyFileMode f convert = do
+ _ <- modifyFileMode' f convert
+ return ()
+modifyFileMode' :: FilePath -> (FileMode -> FileMode) -> IO FileMode
+modifyFileMode' f convert = do
s <- getFileStatus f
- let cur = fileMode s
- let new = convert cur
- when (new /= cur) $
+ let old = fileMode s
+ let new = convert old
+ when (new /= old) $
setFileMode f new
+ return old
+
+{- Runs an action after changing a file's mode, then restores the old mode. -}
+withModifiedFileMode :: FilePath -> (FileMode -> FileMode) -> IO a -> IO a
+withModifiedFileMode file convert a = bracket setup cleanup go
+ where
+ setup = modifyFileMode' file convert
+ cleanup oldmode = modifyFileMode file (const oldmode)
+ go _ = a
{- Removes a FileMode from a file.
- For example, call with otherWriteMode to chmod o-w -}
@@ -28,23 +48,43 @@ unsetFileMode f m = modifyFileMode f $
{- Removes the write bits from a file. -}
preventWrite :: FilePath -> IO ()
-preventWrite f = unsetFileMode f writebits
+preventWrite f = unsetFileMode f $ combineModes writebits
where
- writebits = foldl unionFileModes ownerWriteMode
- [groupWriteMode, otherWriteMode]
+ writebits = [ownerWriteMode, groupWriteMode, otherWriteMode]
{- Turns a file's write bit back on. -}
allowWrite :: FilePath -> IO ()
allowWrite f = modifyFileMode f $
\cur -> cur `unionFileModes` ownerWriteMode
+{- Allows owner and group to read and write to a file. -}
+groupWriteRead :: FilePath -> IO ()
+groupWriteRead f = modifyFileMode f $ \cur -> combineModes
+ [ cur
+ , ownerWriteMode, groupWriteMode
+ , ownerReadMode, groupReadMode
+ ]
+
+{- Allows group to read a file. -}
+groupRead :: FilePath -> IO ()
+groupRead f = modifyFileMode f $ \cur -> combineModes
+ [ cur
+ , ownerReadMode, groupReadMode
+ ]
+
+{- Allows all to read a file. -}
+allRead :: FilePath -> IO ()
+allRead f = modifyFileMode f $ \cur -> combineModes
+ [ cur
+ , ownerReadMode, groupReadMode, otherReadMode
+ ]
+
{- Checks if a file mode indicates it's a symlink. -}
isSymLink :: FileMode -> Bool
isSymLink mode = symbolicLinkMode `intersectFileModes` mode == symbolicLinkMode
{- Checks if a file has any executable bits set. -}
isExecutable :: FileMode -> Bool
-isExecutable mode = ebits `intersectFileModes` mode /= 0
+isExecutable mode = combineModes ebits `intersectFileModes` mode /= 0
where
- ebits = ownerExecuteMode `unionFileModes`
- groupExecuteMode `unionFileModes` otherExecuteMode
+ ebits = [ownerExecuteMode, groupExecuteMode, otherExecuteMode]