func main() { log.SetFlags(log.Flags() | log.Lshortfile) flag.Parse() metaInfo, err := metainfo.LoadFromFile(*torrentPath) if err != nil { log.Fatal(err) } mMapSpan := &mmap_span.MMapSpan{} if len(metaInfo.Info.Files) > 0 { for _, file := range metaInfo.Info.Files { filename := filepath.Join(append([]string{*dataPath, metaInfo.Info.Name}, file.Path...)...) goMMap := fileToMmap(filename, file.Length) mMapSpan.Append(goMMap) } log.Println(len(metaInfo.Info.Files)) } else { goMMap := fileToMmap(*dataPath, metaInfo.Info.Length) mMapSpan.Append(goMMap) } log.Println(mMapSpan.Size()) log.Println(len(metaInfo.Info.Pieces)) info := metaInfo.Info for i := range iter.N(metaInfo.Info.NumPieces()) { p := info.Piece(i) hash := sha1.New() _, err := io.Copy(hash, io.NewSectionReader(mMapSpan, p.Offset(), p.Length())) if err != nil { log.Fatal(err) } fmt.Printf("%d: %x: %v\n", i, p.Hash(), bytes.Equal(hash.Sum(nil), p.Hash().Bytes())) } }
func (cl *Client) AddTorrentFromFile(filename string) (T *Torrent, err error) { mi, err := metainfo.LoadFromFile(filename) if err != nil { return } return cl.AddTorrent(mi) }
func main() { tagflag.Parse(&flags) for _, filename := range flags.TorrentFiles { metainfo, err := metainfo.LoadFromFile(filename) if err != nil { log.Print(err) continue } info := &metainfo.Info.Info if flags.JustName { fmt.Printf("%s\n", metainfo.Info.Name) continue } d := map[string]interface{}{ "Name": info.Name, "NumPieces": info.NumPieces(), "PieceLength": info.PieceLength, } if flags.PieceHashes { d["PieceHashes"] = func() (ret []string) { for i := range iter.N(info.NumPieces()) { ret = append(ret, hex.EncodeToString(info.Pieces[i*20:(i+1)*20])) } return }() } b, _ := json.MarshalIndent(d, "", " ") os.Stdout.Write(b) } if !flags.JustName { os.Stdout.WriteString("\n") } }
func torrentFileInfoHash(fileName string) (ih torrent.InfoHash, ok bool) { mi, _ := metainfo.LoadFromFile(fileName) if mi == nil { return } util.CopyExact(ih[:], mi.Info.Hash) ok = true return }
func main() { flag.Parse() for _, arg := range flag.Args() { mi, err := metainfo.LoadFromFile(arg) if err != nil { log.Fatal(err) } fmt.Printf("%x: %s\n", mi.Info.Hash, arg) } }
func argSpec(arg string) (ts *torrent.TorrentSpec, err error) { if strings.HasPrefix(arg, "magnet:") { return torrent.TorrentSpecFromMagnetURI(arg) } mi, err := metainfo.LoadFromFile(arg) if err != nil { return } ts = torrent.TorrentSpecFromMetaInfo(mi) return }
func main() { var args struct { Files []string `arity:"+" type:"pos"` } tagflag.Parse(&args) for _, arg := range args.Files { mi, err := metainfo.LoadFromFile(arg) if err != nil { log.Fatal(err) } fmt.Printf("%x: %s\n", mi.Info.Hash, arg) } }
func addTorrents(client *torrent.Client) { for _, arg := range opts.Torrent { t := func() *torrent.Torrent { if strings.HasPrefix(arg, "magnet:") { t, err := client.AddMagnet(arg) if err != nil { log.Fatalf("error adding magnet: %s", err) } return t } else { metaInfo, err := metainfo.LoadFromFile(arg) if err != nil { fmt.Fprintf(os.Stderr, "error loading torrent file %q: %s\n", arg, err) os.Exit(1) } t, err := client.AddTorrent(metaInfo) if err != nil { log.Fatal(err) } return t } }() torrentBar(t) err := t.AddPeers(func() (ret []torrent.Peer) { for _, ta := range opts.TestPeer { ret = append(ret, torrent.Peer{ IP: ta.IP, Port: ta.Port, }) } return }()) if err != nil { log.Fatal(err) } go func() { <-t.GotInfo() t.DownloadAll() }() } }
func main() { flag.Parse() metaInfo, err := metainfo.LoadFromFile(*torrentPath) if err != nil { log.Fatal(err) } devZero, err := os.Open("/dev/zero") if err != nil { log.Print(err) } defer devZero.Close() mMapSpan := &mmap_span.MMapSpan{} if len(metaInfo.Info.Files) > 0 { for _, file := range metaInfo.Info.Files { filename := filepath.Join(append([]string{*dataPath, metaInfo.Info.Name}, file.Path...)...) goMMap := fileToMmap(filename, file.Length, devZero) mMapSpan.Append(goMMap) } log.Println(len(metaInfo.Info.Files)) } else { goMMap := fileToMmap(*dataPath, metaInfo.Info.Length, devZero) mMapSpan.Append(goMMap) } log.Println(mMapSpan.Size()) log.Println(len(metaInfo.Info.Pieces)) for piece := 0; piece < (len(metaInfo.Info.Pieces)+sha1.Size-1)/sha1.Size; piece++ { expectedHash := metaInfo.Info.Pieces[sha1.Size*piece : sha1.Size*(piece+1)] if len(expectedHash) == 0 { break } hash := sha1.New() _, err := mMapSpan.WriteSectionTo(hash, int64(piece)*metaInfo.Info.PieceLength, metaInfo.Info.PieceLength) if err != nil { log.Fatal(err) } fmt.Println(piece, bytes.Equal(hash.Sum(nil), expectedHash)) } }
func main() { name := flag.Bool("name", false, "print name") flag.Parse() for _, filename := range flag.Args() { metainfo, err := metainfo.LoadFromFile(filename) if err != nil { log.Print(err) continue } if *name { fmt.Printf("%s\n", metainfo.Info.Name) continue } d := map[string]interface{}{ "Name": metainfo.Info.Name, "NumPieces": metainfo.Info.NumPieces(), } b, _ := json.MarshalIndent(d, "", " ") os.Stdout.Write(b) } if !*name { os.Stdout.WriteString("\n") } }
func main() { log.SetFlags(log.LstdFlags | log.Lshortfile) var rootGroup struct { Client torrent.Config `group:"Client Options"` TestPeers []string `long:"test-peer" description:"address of peer to inject to every torrent"` MMap bool `long:"mmap" description:"memory-map the torrent files"` } // Don't pass flags.PrintError because it's inconsistent with printing. // https://github.com/jessevdk/go-flags/issues/132 parser := flags.NewParser(&rootGroup, flags.HelpFlag|flags.PassDoubleDash) parser.Usage = "[OPTIONS] (magnet URI or .torrent file path)..." posArgs, err := parser.Parse() if err != nil { fmt.Fprintln(os.Stderr, "Download from the BitTorrent network.") fmt.Println(err) os.Exit(2) } testPeers, err := resolvedPeerAddrs(rootGroup.TestPeers) if err != nil { log.Fatal(err) } if rootGroup.MMap { rootGroup.Client.TorrentDataOpener = func(info *metainfo.Info) torrent.Data { ret, err := mmap.TorrentData(info, "") if err != nil { log.Fatalf("error opening torrent data for %q: %s", info.Name, err) } return ret } } if len(posArgs) == 0 { fmt.Fprintln(os.Stderr, "no torrents specified") return } client, err := torrent.NewClient(&rootGroup.Client) if err != nil { log.Fatalf("error creating client: %s", err) } http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { client.WriteStatus(w) }) defer client.Close() for _, arg := range posArgs { t := func() torrent.Torrent { if strings.HasPrefix(arg, "magnet:") { t, err := client.AddMagnet(arg) if err != nil { log.Fatalf("error adding magnet: %s", err) } return t } else { metaInfo, err := metainfo.LoadFromFile(arg) if err != nil { log.Fatal(err) } t, err := client.AddTorrent(metaInfo) if err != nil { log.Fatal(err) } return t } }() err := t.AddPeers(testPeers) if err != nil { log.Fatal(err) } go func() { <-t.GotInfo() t.DownloadAll() }() } done := make(chan struct{}) go func() { defer close(done) if client.WaitAll() { log.Print("downloaded ALL the torrents") } else { log.Fatal("y u no complete torrents?!") } }() ticker := time.NewTicker(time.Second) waitDone: for { select { case <-done: break waitDone case <-ticker.C: os.Stdout.WriteString(progressLine(client)) } } if rootGroup.Client.Seed { select {} } }
func main() { log.SetFlags(log.LstdFlags | log.Lshortfile) var rootGroup struct { Client torrent.Config `group:"Client Options"` TestPeers []string `long:"test-peer" description:"address of peer to inject to every torrent"` Pick string `long:"pick" description:"filename to pick"` } // Don't pass flags.PrintError because it's inconsistent with printing. // https://github.com/jessevdk/go-flags/issues/132 parser := flags.NewParser(&rootGroup, flags.HelpFlag|flags.PassDoubleDash) parser.Usage = "[OPTIONS] (magnet URI or .torrent file path)..." posArgs, err := parser.Parse() if err != nil { fmt.Fprintln(os.Stderr, "Download from the BitTorrent network.\n") fmt.Println(err) os.Exit(2) } log.Printf("File to pick: %s", rootGroup.Pick) testPeers, err := resolvedPeerAddrs(rootGroup.TestPeers) if err != nil { log.Fatal(err) } if len(posArgs) == 0 { fmt.Fprintln(os.Stderr, "no torrents specified") return } tmpdir, err := ioutil.TempDir("", "torrent-pick-") if err != nil { log.Fatal(err) } defer os.RemoveAll(tmpdir) rootGroup.Client.DataDir = tmpdir client, err := torrent.NewClient(&rootGroup.Client) if err != nil { log.Fatalf("error creating client: %s", err) } http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { client.WriteStatus(w) }) defer client.Close() dstName := dstFileName(rootGroup.Pick) f, err := os.Create(dstName) if err != nil { log.Fatal(err) } dstWriter := bufio.NewWriter(f) done := make(chan struct{}) for _, arg := range posArgs { t := func() torrent.Torrent { if strings.HasPrefix(arg, "magnet:") { t, err := client.AddMagnet(arg) if err != nil { log.Fatalf("error adding magnet: %s", err) } return t } else { metaInfo, err := metainfo.LoadFromFile(arg) if err != nil { log.Fatal(err) } t, err := client.AddTorrent(metaInfo) if err != nil { log.Fatal(err) } return t } }() err := t.AddPeers(testPeers) if err != nil { log.Fatal(err) } go func() { defer close(done) <-t.GotInfo() for _, file := range t.Files() { if file.DisplayPath() != rootGroup.Pick { continue } srcReader := io.NewSectionReader(t.NewReader(), file.Offset(), file.Length()) io.Copy(dstWriter, srcReader) return } log.Print("file not found") }() } ticker := time.NewTicker(time.Second) waitDone: for { select { case <-done: break waitDone case <-ticker.C: os.Stdout.WriteString(progressLine(client)) } } if rootGroup.Client.Seed { select {} } }
func main() { log.SetFlags(log.LstdFlags | log.Lshortfile) var opts struct { torrent.Config `name:"Client"` Mmap bool `help:"memory-map torrent data"` TestPeer []*net.TCPAddr `short:"p" help:"addresses of some starting peers"` Torrent []string `type:"pos" arity:"+" help:"torrent file path or magnet uri"` } tagflag.Parse(&opts, tagflag.SkipBadTypes()) clientConfig := opts.Config if opts.Mmap { clientConfig.TorrentDataOpener = func(info *metainfo.Info) torrent.Data { ret, err := mmap.TorrentData(info, "") if err != nil { log.Fatalf("error opening torrent data for %q: %s", info.Name, err) } return ret } } torrents := opts.Torrent if len(torrents) == 0 { fmt.Fprintf(os.Stderr, "no torrents specified\n") return } client, err := torrent.NewClient(&clientConfig) if err != nil { log.Fatalf("error creating client: %s", err) } http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { client.WriteStatus(w) }) defer client.Close() for _, arg := range torrents { t := func() torrent.Torrent { if strings.HasPrefix(arg, "magnet:") { t, err := client.AddMagnet(arg) if err != nil { log.Fatalf("error adding magnet: %s", err) } return t } else { metaInfo, err := metainfo.LoadFromFile(arg) if err != nil { fmt.Fprintf(os.Stderr, "error loading torrent file %q: %s\n", arg, err) os.Exit(1) } t, err := client.AddTorrent(metaInfo) if err != nil { log.Fatal(err) } return t } }() err := t.AddPeers(func() (ret []torrent.Peer) { for _, ta := range opts.TestPeer { ret = append(ret, torrent.Peer{ IP: ta.IP, Port: ta.Port, }) } return }()) if err != nil { log.Fatal(err) } go func() { <-t.GotInfo() t.DownloadAll() }() } done := make(chan struct{}) go func() { defer close(done) if client.WaitAll() { log.Print("downloaded ALL the torrents") } else { log.Fatal("y u no complete torrents?!") } }() ticker := time.NewTicker(time.Second) waitDone: for { select { case <-done: break waitDone case <-ticker.C: os.Stdout.WriteString(progressLine(client)) } } if opts.Seed { select {} } }