1 {-# LANGUAGE OverloadedStrings #-}
4 import Prelude hiding (log, length, readFile)
5 import Data.ByteString.Char8 (ByteString, readFile, unpack)
6 import System.Environment (getArgs)
7 import System.Exit (exitSuccess)
8 import System.Directory (doesFileExist)
10 import FuncTorrent.Bencode (decode)
11 import FuncTorrent.Logger (initLogger, logMessage, logStop)
12 import FuncTorrent.Metainfo (Info(..), Metainfo(..), mkMetaInfo)
13 import FuncTorrent.Peer (handShake, msgLoop)
14 import FuncTorrent.Tracker (peers, getTrackerResponse)
16 logError :: String -> (String -> IO ()) -> IO ()
17 logError e logMsg = logMsg $ "parse error: \n" ++ e
20 peerId = "-HS0001-*-*-20150215"
26 usage = putStrLn "usage: functorrent torrent-file"
28 parse :: [String] -> IO ByteString
29 parse [] = usage >> exit
31 fileExist <- doesFileExist a
34 else error "file does not exist"
37 torrentToMetaInfo :: ByteString -> Either String Metainfo
49 let log = logMessage logR
50 log "Starting up functorrent"
51 log $ "Parsing arguments " ++ concat args
52 torrentStr <- parse args
53 case (torrentToMetaInfo torrentStr) of
56 log $ "Downloading file : " ++ name (info m)
57 log "Trying to fetch peers"
59 log $ "Trackers: " ++ head (announceList m)
60 trackerResp <- getTrackerResponse m peerId
63 log $ "Peers List : " ++ (show . peers $ peerList)
64 let p1 = head (peers peerList)
65 h <- handShake p1 (infoHash m) peerId
67 msgLoop h (pieces (info m))
68 Left e -> log $ "Error" ++ unpack e
69 Left e -> logError e log