, len = pLen })
| (i, h, pLen) <- zip3 [0..numPieces] hashes pLengths]
hashes = splitN 20 pieceHash
- pLengths = (splitNum fileLen pieceLen)
+ pLengths = splitNum fileLen pieceLen
pieceMapFromFile :: FilePath -> PieceMap -> IO PieceMap
-pieceMapFromFile filePath pieceMap = do
+pieceMapFromFile filePath pieceMap =
traverseWithKey f pieceMap
- where
- f k v = do
- let offset = if k == 0 then 0 else k * len (pieceMap ! (k - 1))
- isHashValid <- (flip verifyHash) (hash v) <$> (readFileAtOffset filePath offset (len v))
- if isHashValid
- then return $ v { dlstate = Have }
- else return $ v
+ where
+ f k v = do
+ let offset = if k == 0 then 0 else k * len (pieceMap ! (k - 1))
+ isHashValid <- flip verifyHash (hash v) <$> readFileAtOffset filePath offset (len v)
+ if isHashValid
+ then return $ v { dlstate = Have }
+ else return v
havePiece :: PieceMap -> Integer -> Bool
havePiece pm index =
return ()
doHandshake False h peer infoHash peerid = do
let hs = genHandshakeMsg infoHash peerid
- putStrLn $ "waiting for a handshake"
+ putStrLn "waiting for a handshake"
hsMsg <- hGet h (length (unpack hs))
putStrLn $ "<-- handshake from peer: " ++ show peer
let rxInfoHash = take 20 $ drop 28 hsMsg
if rxInfoHash /= infoHash
then do
- putStrLn $ "infoHashes does not match"
+ putStrLn "infoHashes does not match"
hClose h
return ()
else do
pBS <- liftIO $ downloadPiece h workPiece pLen
if not $ verifyHash pBS (hash (pieceStatus ! workPiece))
then
- liftIO $ putStrLn $ "Hash mismatch"
+ 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
NotInterestedMsg -> do
modify (\st -> st {heInterested = False})
msgLoop pieceStatus file
- CancelMsg _ _ _ -> do -- check if valid index, begin, length
+ CancelMsg _ _ _ -> -- check if valid index, begin, length
msgLoop pieceStatus file
- PortMsg _ -> do
+ PortMsg _ ->
msgLoop pieceStatus file
-- handle RequestMsg, HaveMsg. No need to handle PieceMsg here.
-- also BitFieldMsg
import Prelude hiding (writeFile, take)
import qualified Crypto.Hash.SHA1 as SHA1 (hash)
+import Control.Monad (unless)
import Data.ByteString (ByteString, writeFile, hPut, hGet, take)
import qualified Data.ByteString.Char8 as BC
import System.IO (withFile, hSeek, IOMode(..), SeekMode(..))
createDummyFile :: FilePath -> Int -> IO ()
createDummyFile path size = do
dfe <- doesFileExist path
- if dfe
- then return ()
- else
+ unless dfe $
writeFile path (BC.replicate size '\0')
-- write into a file at a specific offet