module ArTimestampWiper where
import Control.Applicative
import Control.Monad
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as BS8
import Data.Char
import System.IO
arFileWipeTimeStamps :: FilePath -> IO ()
arFileWipeTimeStamps path = withBinaryFile path ReadWriteMode $ \h -> do
archiveSize <- hFileSize h
let go entryOffset | entryOffset == archiveSize = return ()
| entryOffset > archiveSize = die "Archive truncated"
| odd entryOffset = go (entryOffset + 1)
| otherwise = do
magic <- goto 58 >> BS.hGet h 2
when (magic /= "\x60\x0a") $ die "Bad ar magic"
size <- goto 48 >> parseSize . BS8.unpack <$> BS.hGet h 10
goto 16 >> BS.hPut h "0 "
go (entryOffset + 60 + size)
where
goto pos = hSeek h AbsoluteSeek (entryOffset + pos)
parseSize x = case reads x of
[(s, r)] | all isSpace r -> s
_ -> die "Malformed header"
die msg = error $ "arFileWipeTimeStamps: " ++ path ++ ": "
++ msg ++ " at offset " ++ show entryOffset
go 8