Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
-- effecient replacement for "... | xargs ar q libfoo.a" -- usage: -- find -name '*.o' | arq libfoo.a import System.Environment (getArgs) import System.IO import Monad (liftM, unless, when) import qualified System.Posix.Types as Posix import qualified System.Posix.Files as Posix import Foreign (allocaBytes) import Numeric (showOct) data ArEntryHeader = ArEntryHeader { fileName :: String, -- 0 15 File name ASCII fileDate :: Posix.EpochTime, -- 16 27 File date Decimal ownerID :: Posix.UserID, -- 28 33 Owner ID Decimal groupID :: Posix.GroupID, -- 34 39 Group ID Decimal fileMode :: Posix.FileMode, -- 40 47 File mode Octal fileSize :: Posix.FileOffset -- 48 57 File size Decimal -- 58 59 Header magic "`\n" --fileData -- 60 60+size File data } main = do [arFile] <- getArgs oFiles <- liftM words getContents hnd <- openBinaryFile arFile WriteMode hPutStr hnd "!\n" let extendedFileNames = filter ((>15) . length) (map basenameOf oFiles) unless (null extendedFileNames) $ do let sectionSize = sum (map ((+2) . length) extendedFileNames) content [] = "" content (f:fs) = f ++ '/' : '\n' : content fs hPutChars hnd 48 "//" hPutChars hnd 10 (show sectionSize) hPutChar hnd '`' hPutChar hnd '\n' hPutStr hnd (content extendedFileNames) when (sectionSize `mod` 2 == 1) (hPutChar hnd '\n') let loop _ [] = return () loop offset (fname:fnames) = do let basename = basenameOf fname status <- Posix.getFileStatus fname file <- openBinaryFile fname ReadMode hPutArEntryHeader hnd ArEntryHeader { fileName = if length basename > 15 then '/' : show offset else basename ++ "/", fileDate = Posix.modificationTime status, ownerID = Posix.fileOwner status, groupID = Posix.fileGroup status, fileMode = Posix.fileMode status, fileSize = Posix.fileSize status } hCopy hnd file when (Posix.fileSize status `mod` 2 == 1) (hPutChar hnd '\n') hClose file let offset' | length basename > 15 = offset + 2 + length basename | otherwise = offset loop offset' fnames loop 0 oFiles hClose hnd basenameOf = reverse . (takeWhile (/='/')) . reverse hPutArEntryHeader hnd entry = do hPutChars hnd 16 (fileName entry) hPutChars hnd 12 (show (fileDate entry)) hPutChars hnd 6 (show (ownerID entry)) hPutChars hnd 6 (show (groupID entry)) hPutChars hnd 8 (showOct (fileMode entry) []) hPutChars hnd 10 (show (fileSize entry)) hPutChar hnd '`' hPutChar hnd '\n' hPutChars hnd n str | length str <= n = hPutStr hnd (take n (str ++ repeat ' ')) hCopy :: Handle -> Handle -> IO () hCopy oh ih = let blockSize = 1024 * 16 in allocaBytes blockSize $ \buf -> do let loop = do bytes <- hGetBuf ih buf blockSize hPutBuf oh buf bytes when (bytes == blockSize) loop loop