cmd/torrent-create/main.go | 3 +++ cmd/torrent-verify/main.go | 71 +++++++++++++++++++++++++++++++++-------------------- dht/dht.go | 10 ++++++---- mmap_span/span.go | 4 +--- diff --git a/cmd/torrent-create/main.go b/cmd/torrent-create/main.go index 65978b76f7ab2e854ff037c835fb9669c18d8c1a..3f80a9282d957164be9879d6847acbd9da47608a 100644 --- a/cmd/torrent-create/main.go +++ b/cmd/torrent-create/main.go @@ -26,6 +26,9 @@ func main() { b := torrent.Builder{} for _, filename := range flag.Args() { + if _, err := os.Stat(filename); os.IsNotExist(err) { + log.Fatal(err) + } if err := filepath.Walk(filename, func(path string, info os.FileInfo, err error) error { log.Print(path) if info.IsDir() { diff --git a/cmd/torrent-verify/main.go b/cmd/torrent-verify/main.go index 9aae543ff6dccc7800a6fc5fc164da8f297ed4ac..061932e4a0fbabe9257f13b807ea22e395197a74 100644 --- a/cmd/torrent-verify/main.go +++ b/cmd/torrent-verify/main.go @@ -16,16 +16,40 @@ "github.com/anacrolix/torrent/mmap_span" ) var ( - filePath = flag.String("torrent", "/path/to/the.torrent", "path of the torrent file") - dirPath = flag.String("path", "/torrent/data", "path of the torrent data") + torrentPath = flag.String("torrent", "/path/to/the.torrent", "path of the torrent file") + dataPath = flag.String("path", "/torrent/data", "path of the torrent data") + summary = flag.Bool("summary", false, "display summary at the end") ) -func init() { - flag.Parse() +func verifySummary(sMap map[bool][]int) { + fmt.Println("----------------") + fmt.Println(" TORRENT-VERIFY ") + fmt.Println("----------------") + fmt.Printf("Number of correct pieces: %d\n", len(sMap[true])) + fmt.Printf("Number of wrong pieces: %d\n", len(sMap[false])) +} + +func fileToMmap(filename string, length int64, devZero *os.File, mMapSpan *mmap_span.MMapSpan) { + osFile, err := os.Open(filename) + if err != nil { + log.Fatal(err) + } + mmapFd := osFile.Fd() + goMMap, err := gommap.MapRegion(mmapFd, 0, length, gommap.PROT_READ, gommap.MAP_PRIVATE) + if err != nil { + log.Fatal(err) + } + if int64(len(goMMap)) != length { + log.Printf("file mmap has wrong size: %#v", filename) + } + osFile.Close() + mMapSpan.Append(goMMap) } func main() { - metaInfo, err := metainfo.LoadFromFile(*filePath) + flag.Parse() + summaryMap := make(map[bool][]int) + metaInfo, err := metainfo.LoadFromFile(*torrentPath) if err != nil { log.Fatal(err) } @@ -34,31 +58,19 @@ if err != nil { log.Print(err) } defer devZero.Close() - var mMapSpan *mmap_span.MMapSpan - for _, file := range metaInfo.Info.Files { - filename := filepath.Join(append([]string{*dirPath, metaInfo.Info.Name}, file.Path...)...) - osFile, err := os.Open(filename) - mmapFd := osFile.Fd() - if err != nil { - if pe, ok := err.(*os.PathError); ok && pe.Err.Error() == "no such file or directory" { - mmapFd = devZero.Fd() - } else { - 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...)...) + fileToMmap(filename, file.Length, devZero, mMapSpan) } - goMMap, err := gommap.MapRegion(mmapFd, 0, file.Length, gommap.PROT_READ, gommap.MAP_PRIVATE) - if err != nil { - log.Fatal(err) - } - if int64(len(goMMap)) != file.Length { - log.Printf("file mmap has wrong size: %#v", filename) - } - osFile.Close() - mMapSpan.Append(goMMap) + log.Println(len(metaInfo.Info.Files)) + } else { + fileToMmap(*dataPath, metaInfo.Info.Length, devZero, mMapSpan) } - log.Println(len(metaInfo.Info.Files)) log.Println(mMapSpan.Size()) log.Println(len(metaInfo.Info.Pieces)) + var pieceValid bool 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 { @@ -69,6 +81,11 @@ _, 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)) + pieceValid = bytes.Equal(hash.Sum(nil), expectedHash) + summaryMap[pieceValid] = append(summaryMap[pieceValid], piece) + fmt.Println(piece, pieceValid) + } + if *summary { + verifySummary(summaryMap) } } diff --git a/dht/dht.go b/dht/dht.go index deb45e79449afb6cbb22bee2b96cd37b350600a0..116da78fa1635cc1665e18671a0e049201e24789 100644 --- a/dht/dht.go +++ b/dht/dht.go @@ -980,11 +980,13 @@ "router.bittorrent.com:6881", } } for _, addrStr := range bootstrapNodes { - udpAddr, err := net.ResolveUDPAddr("udp4", addrStr) - if err != nil { - continue + if addrStr != "" { + udpAddr, err := net.ResolveUDPAddr("udp4", addrStr) + if err != nil { + continue + } + addrs = append(addrs, udpAddr) } - addrs = append(addrs, udpAddr) } if len(addrs) == 0 { err = errors.New("nothing resolved") diff --git a/mmap_span/span.go b/mmap_span/span.go index 5db9588536d37ab4c70ceef7edc675b27e376406..622c179a282633d9de37649198e12622102492e8 100644 --- a/mmap_span/span.go +++ b/mmap_span/span.go @@ -4,9 +4,7 @@ type sizer interface { Size() int64 } -type ( - span []sizer -) +type span []sizer func (me span) ApplyTo(off int64, f func(int64, sizer) (stop bool)) { for _, interval := range me {