]> Sergey Matveev's repositories - btrtrc.git/blob - cmd/btrtrc/main.go
cmd/btrtrc client
[btrtrc.git] / cmd / btrtrc / main.go
1 package main
2
3 import (
4         "flag"
5         "log"
6         "net"
7         "os"
8         "os/signal"
9         "strings"
10         "sync"
11         "syscall"
12
13         "github.com/anacrolix/dht/v2"
14         analog "github.com/anacrolix/log"
15         "golang.org/x/time/rate"
16
17         "github.com/anacrolix/torrent"
18         "github.com/anacrolix/torrent/storage"
19 )
20
21 const (
22         TorrentExt = ".torrent"
23         UserAgent  = "btrtrc/0.2.0"
24 )
25
26 var (
27         Cancel = make(chan struct{})
28         Jobs   sync.WaitGroup
29 )
30
31 func main() {
32         log.SetFlags(log.Ldate | log.Ltime)
33         fifosDir := flag.String("fifos", "fifos", "Path to fifos/")
34         txsDir := flag.String("txs", "txs", "Path to txs/")
35         dhtBoot := flag.String("dht", "dht.cypherpunks.ru:8991",
36                 "Comma-separated list of DHT bootstrap nodes")
37         addr := flag.String("bind", "[::]:6881", "Address to bind to")
38         pub4 := flag.String("4", "", "External IPv4 address")
39         pub6 := flag.String("6", "", "External IPv6 address")
40         debug := flag.Bool("debug", false, "Enable debug messages")
41         noDHT := flag.Bool("nodht", false, "Disable DHT")
42         rxRate := flag.Int("rx-rate", 0, "Download rate, piece bytes/sec")
43         txRate := flag.Int("rt-rate", 0, "Upload rate, bytes/sec")
44         verify := flag.Bool("verify", false, "Force verification of provided torrents")
45         flag.Parse()
46
47         FIFOsDir = *fifosDir
48         TxsDir = *txsDir
49         os.MkdirAll(TxsDir, 0777)
50         dht.DefaultGlobalBootstrapHostPorts = strings.Split(*dhtBoot, ",")
51         cc := torrent.NewDefaultClientConfig()
52         cc.Debug = *debug
53         cc.DisableAcceptRateLimiting = true
54         cc.NoDefaultPortForwarding = true
55         cc.DisableWebtorrent = true
56         cc.Logger = analog.Default.WithNames("main", "client")
57         cc.HTTPUserAgent = UserAgent
58         cc.ExtendedHandshakeClientVersion = UserAgent
59         cc.DefaultStorage = storage.NewFileWithCompletion(".", NewBFPieceCompletion())
60         if *verify {
61                 doVerify(cc, flag.Args())
62                 return
63         }
64         cc.Seed = true
65         if *pub4 == "" {
66                 cc.DisableIPv4 = true
67         } else {
68                 cc.PublicIp4 = net.ParseIP(*pub4).To4()
69         }
70         if *pub6 == "" {
71                 cc.DisableIPv6 = true
72         } else {
73                 cc.PublicIp6 = net.ParseIP(*pub6).To16()
74         }
75         if *txRate != 0 {
76                 cc.UploadRateLimiter = rate.NewLimiter(rate.Limit(*txRate), 256<<10)
77         }
78         if *rxRate != 0 {
79                 cc.DownloadRateLimiter = rate.NewLimiter(rate.Limit(*rxRate), 1<<16)
80         }
81         cc.NoDHT = *noDHT
82         cc.SetListenAddr(*addr)
83         client, err := torrent.NewClient(cc)
84         if err != nil {
85                 log.Fatalln("torrent.NewClient:", err)
86         }
87         defer client.Close()
88
89         needsShutdown := make(chan os.Signal)
90         signal.Notify(needsShutdown, syscall.SIGTERM, syscall.SIGINT)
91         go func() {
92                 <-needsShutdown
93                 close(Cancel)
94                 client.Close()
95         }()
96
97         fifosPrepare()
98         log.Println("started", client.PublicIPs())
99         Jobs.Add(1)
100         go overallStatus(client)
101         go fifoList(client)
102         go fifoTopSeed(client)
103         go fifoDHTList(client)
104         go fifoAdd(client)
105         go fifoDel(client)
106         Jobs.Add(1)
107         go txStatsDumper(client)
108         <-client.Closed()
109         Jobs.Wait()
110         fifosCleanup()
111         log.Println("finished")
112 }