]> Sergey Matveev's repositories - btrtrc.git/blob - cmd/torrent/main.go
Abstract the status HTTP server into package util
[btrtrc.git] / cmd / torrent / main.go
1 package main
2
3 import (
4         "bitbucket.org/anacrolix/go.torrent/dht"
5         "bitbucket.org/anacrolix/go.torrent/util"
6         "flag"
7         "fmt"
8         "log"
9         "net"
10         "net/http"
11         _ "net/http/pprof"
12         "os"
13         "strings"
14
15         "github.com/anacrolix/libtorgo/metainfo"
16
17         "bitbucket.org/anacrolix/go.torrent"
18 )
19
20 var (
21         downloadDir = flag.String("downloadDir", "", "directory to store download torrent data")
22         testPeer    = flag.String("testPeer", "", "bootstrap peer address")
23         httpAddr    = flag.String("httpAddr", "localhost:0", "http serve address")
24         // TODO: Check the default torrent listen port.
25         listenAddr      = flag.String("listenAddr", ":6882", "incoming connection address")
26         disableTrackers = flag.Bool("disableTrackers", false, "disable trackers")
27         seed            = flag.Bool("seed", false, "seed after downloading")
28 )
29
30 func init() {
31         log.SetFlags(log.LstdFlags | log.Lshortfile)
32         flag.Parse()
33 }
34
35 func makeListener() net.Listener {
36         l, err := net.Listen("tcp", *listenAddr)
37         if err != nil {
38                 log.Fatal(err)
39         }
40         return l
41 }
42
43 func main() {
44         if *httpAddr != "" {
45                 util.LoggedHTTPServe(*httpAddr)
46         }
47         dhtServer := &dht.Server{
48                 Socket: func() *net.UDPConn {
49                         addr, err := net.ResolveUDPAddr("udp4", *listenAddr)
50                         if err != nil {
51                                 log.Fatalf("error resolving dht listen addr: %s", err)
52                         }
53                         s, err := net.ListenUDP("udp4", addr)
54                         if err != nil {
55                                 log.Fatalf("error creating dht socket: %s", err)
56                         }
57                         return s
58                 }(),
59         }
60         err := dhtServer.Init()
61         if err != nil {
62                 log.Fatalf("error initing dht server: %s", err)
63         }
64         go func() {
65                 err := dhtServer.Serve()
66                 if err != nil {
67                         log.Fatalf("error serving dht: %s", err)
68                 }
69         }()
70         go func() {
71                 err := dhtServer.Bootstrap()
72                 if err != nil {
73                         log.Printf("error bootstrapping dht server: %s", err)
74                 }
75         }()
76         client := torrent.Client{
77                 DataDir:         *downloadDir,
78                 Listener:        makeListener(),
79                 DisableTrackers: *disableTrackers,
80                 DHT:             dhtServer,
81         }
82         http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
83                 client.WriteStatus(w)
84         })
85         client.Start()
86         defer client.Stop()
87         if flag.NArg() == 0 {
88                 fmt.Fprintln(os.Stderr, "no torrents specified")
89                 return
90         }
91         for _, arg := range flag.Args() {
92                 var ih torrent.InfoHash
93                 if strings.HasPrefix(arg, "magnet:") {
94                         m, err := torrent.ParseMagnetURI(arg)
95                         if err != nil {
96                                 log.Fatalf("error parsing magnet uri: %s", err)
97                         }
98                         ih = m.InfoHash
99                         err = client.AddMagnet(arg)
100                         if err != nil {
101                                 log.Fatalf("error adding magnet: %s", err)
102                         }
103                 } else {
104                         metaInfo, err := metainfo.LoadFromFile(arg)
105                         if err != nil {
106                                 log.Fatal(err)
107                         }
108                         err = client.AddTorrent(metaInfo)
109                         if err != nil {
110                                 log.Fatal(err)
111                         }
112                         ih = torrent.BytesInfoHash(metaInfo.Info.Hash)
113                 }
114                 client.PrioritizeDataRegion(ih, 0, 999999999)
115                 err := client.AddPeers(ih, func() []torrent.Peer {
116                         if *testPeer == "" {
117                                 return nil
118                         }
119                         addr, err := net.ResolveTCPAddr("tcp", *testPeer)
120                         if err != nil {
121                                 log.Fatal(err)
122                         }
123                         return []torrent.Peer{{
124                                 IP:   addr.IP,
125                                 Port: addr.Port,
126                         }}
127                 }())
128                 if err != nil {
129                         log.Fatal(err)
130                 }
131         }
132         if *seed {
133                 select {}
134         }
135         if client.WaitAll() {
136                 log.Print("all torrents completed!")
137         } else {
138                 log.Fatal("y u no complete torrents?!")
139         }
140 }