import Data.Bits
import Data.Word (Word8)
import Data.Map (Map, fromList, toList, (!), mapWithKey, traverseWithKey, adjust, filter)
-import qualified Crypto.Hash.SHA1 as SHA1 (hash)
import Safe (headMay)
import FuncTorrent.Metainfo (Info(..), Metainfo(..))
-import FuncTorrent.Utils (splitN, splitNum, writeFileAtOffset, readFileAtOffset)
+import FuncTorrent.Utils (splitN, splitNum, writeFileAtOffset, readFileAtOffset, verifyHash)
import FuncTorrent.PeerMsgs (Peer(..), PeerMsg(..), sendMsg, getMsg, genHandshakeMsg)
data PState = PState { handle :: Handle
pBS <- liftIO $ downloadPiece h workPiece pLen
if not $ verifyHash pBS (hash (pieceStatus ! workPiece))
then
- liftIO $ putStrLn $ "Hash mismatch: " ++ show (hash (pieceStatus ! workPiece)) ++ " vs " ++ show (take 20 (SHA1.hash pBS))
+ liftIO $ putStrLn $ "Hash mismatch"
else do
let fileOffset = if workPiece == 0 then 0 else workPiece * len (pieceStatus ! (workPiece - 1))
liftIO $ putStrLn $ "Write into file at offset: " ++ show fileOffset
putStrLn "ignoring irrelevant msg"
return empty)
-verifyHash :: ByteString -> ByteString -> Bool
-verifyHash bs pieceHash =
- take 20 (SHA1.hash bs) == pieceHash
writeFileAtOffset,
readFileAtOffset,
splitNum,
- splitN
+ splitN,
+ verifyHash
)
where
-import Prelude hiding (writeFile)
+import Prelude hiding (writeFile, take)
+import qualified Crypto.Hash.SHA1 as SHA1 (hash)
+import Data.ByteString (ByteString, writeFile, hPut, hGet, take)
+import qualified Data.ByteString.Char8 as BC
import System.IO (withFile, hSeek, IOMode(..), SeekMode(..))
import System.Directory (doesFileExist)
-import Data.ByteString (ByteString, writeFile, hPut, hGet)
-import qualified Data.ByteString.Char8 as BC
splitN :: Int -> BC.ByteString -> [BC.ByteString]
splitN n bs | BC.null bs = []
withFile path ReadWriteMode (\h -> do
hSeek h AbsoluteSeek offset
hGet h (fromInteger len))
+
+verifyHash :: ByteString -> ByteString -> Bool
+verifyHash bs pieceHash =
+ take 20 (SHA1.hash bs) == pieceHash