-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTorrent.hs
More file actions
53 lines (47 loc) · 1.43 KB
/
Torrent.hs
File metadata and controls
53 lines (47 loc) · 1.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
module Torrent where
import Files
import Files.MMap
import MetaInfo
import Peer.Connection
import Peer.Env
import Tracker
import Torrent.Env
import HTorrentPrelude
import Data.Array
import qualified Data.ByteString as BS
import Network.Socket
import System.Random
splitPieces :: ByteString -> [ByteString]
splitPieces = unfoldr f
where f bs = guard (not (BS.null bs)) >> Just (BS.splitAt 20 bs)
pieceArray :: Int -> [ByteString] -> Array Int ByteString
pieceArray n bs = listArray (0, n - 1) bs
initTorrent :: MetaInfo -> PortNumber -> IO TorrentEnv
initTorrent m p = do
id <- replicateM 20 randomIO
let fs = initFileMap (m ^. info)
let torrentInfo = TorrentInfo {
_torrentName = m ^. info . name,
_torrentHash = m ^. info . hash,
_tracker = m ^. announce,
_numPieces = pn,
_pieceLength = m ^. info . piece_length,
_localId = BS.pack id,
_portNumber = p,
_uploaded = 0,
_pieceHash = pa,
_files = fs
}
initTorrentEnv torrentInfo
where ps = splitPieces (m ^. info . pieceHashes)
pn = length ps
pa = pieceArray pn ps
startTorrent :: MetaInfo -> PortNumber -> IO (Maybe TorrentEnv)
startTorrent m p = do
env <- initTorrent m p
tr <- trackerRequest (env ^. torrentInfo)
case tr of
Just (_, as) -> do
mapM (forkIO . peerThread env) as
return (Just env)
Nothing -> return Nothing