Haskell noob here。我有一個關於如何使用現有庫的具體問題,可能會導致Haskell正確使用的一些更基本的方面。如何覆蓋Codec.Archive.Tar中的函數
我正在學習Haskell,並且在學習的時候有一個小項目在工作。該腳本需要找到給定目錄中的所有tarball,並將它們並行打包。在這一點上,我正在研究拆包的基本功能。因此,使用Codec.Archive.Tar軟件包,我怎樣才能用完全合格的路徑覆蓋它對tarball的行爲?
下面是一些示例代碼:
module Main where
import qualified Codec.Archive.Tar as Tar
import qualified Codec.Compression.GZip as GZip
import Control.Monad (liftM, unless)
import qualified Data.ByteString.Lazy as BS
import System.Directory (doesDirectoryExist, getDirectoryContents)
import System.Exit (exitWith, ExitCode(..))
import System.FilePath.Posix (takeExtension)
searchPath = "/home/someuser/tarball/dir"
exit = exitWith ExitSuccess
die = exitWith (ExitFailure 1)
processFile :: String -> IO()
processFile file = do
putStrLn $ "Unpacking " ++ file ++ " to " ++ searchPath
Tar.unpack searchPath . Tar.read . GZip.decompress =<< BS.readFile filePath
where filePath = searchPath ++ "/" ++ file
main = do
dirExists <- doesDirectoryExist searchPath
unless dirExists $ (putStrLn $ "Error: Search path not found: " ++ searchPath) >> die
files <- targetFiles `liftM` getDirectoryContents searchPath
mapM_ processFile files
exit
where targetFiles = filter (\f -> f /= "." && f /= ".." && takeExtension f == ".tgz")
當我用tar包的目錄中擠滿了這條命令:
tar czvPf myfile.tgz /tarball_testing/myfile
我得到以下輸出:
Unpacking myfile.tgz to /tarball_testing
unpacker.hs: Absolute file name in tar archive: "/tarball_testing/myfile"
第二行是問題。閱讀文檔Codec.Archive.Tar我沒有看到一種方法來禁用此功能(對於我爲什麼要在tarball中使用完整路徑或者相關安全影響的討論沒有興趣)。
首先想到的是,我不知何故需要重寫該函數,但並不像「專業版Haskeller」那樣「感覺」。我可以在正確的方向得到一個指針嗎?
從我的文檔掃描爲['tar'包](http://hackage.haskell.org/package/tar),它看起來像提供文件提供的唯一接口將拒絕絕對路徑。你可以用這個軟件包做任何事情。 – Carl
可能有用的一件事是使用['mapEntries'](http://hackage.haskell.org/package/tar-0.3.1.0/docs/Codec-Archive-Tar.html#v:mapEntries)以及工具['Codec.Archive.Tar.Entry'](http://hackage.haskell.org/package/tar-0.3.1.0/docs/Codec-Archive-Tar-Entry.html)和'System.FilePath'來製作提取之前的相對入口路徑。 – duplode