12 "github.com/anacrolix/tagflag"
14 "github.com/anacrolix/torrent"
15 "github.com/anacrolix/torrent/metainfo"
16 "github.com/anacrolix/torrent/tracker"
19 func argSpec(arg string) (ts *torrent.TorrentSpec, err error) {
20 if strings.HasPrefix(arg, "magnet:") {
21 return torrent.TorrentSpecFromMagnetURI(arg)
23 mi, err := metainfo.LoadFromFile(arg)
27 ts = torrent.TorrentSpecFromMetaInfo(mi)
35 Torrents []string `arity:"+"`
42 for _, arg := range flags.Torrents {
43 ts, err := argSpec(arg)
47 for _, tier := range ts.Trackers {
48 for _, tURI := range tier {
49 ar := tracker.AnnounceRequest{
53 InfoHash: ts.InfoHash,
56 go func(tURI string) {
58 if doTracker(tURI, ar) {
59 atomic.StoreInt32(&exitCode, 1)
66 os.Exit(int(exitCode))
69 func doTracker(tURI string, ar tracker.AnnounceRequest) (hadError bool) {
70 for _, res := range announces(tURI, ar) {
72 resp := res.AnnounceResponse
75 log.Printf("error announcing to %q: %s", tURI, err)
78 fmt.Printf("response from %q: %+v\n", tURI, resp)
83 type announceResult struct {
84 tracker.AnnounceResponse
88 func announces(uri string, ar tracker.AnnounceRequest) (ret []announceResult) {
89 u, err := url.Parse(uri)
91 return []announceResult{{error: err}}
93 a := tracker.Announce{
97 if u.Scheme == "udp" {
99 ret = append(ret, announce(a))
100 a.UdpNetwork = "udp6"
101 ret = append(ret, announce(a))
104 return []announceResult{announce(a)}
107 func announce(a tracker.Announce) announceResult {
109 return announceResult{resp, err}