torrent-create and torrent-verify did not work correctly when a single file is present in metainfo torrent file. torrent-create now fails if the path passed as an argument does not exist. I've als modified dht.go which now handles the case when an empty string is passed in DHT bootstrap nodes slice. Finally in span.go I've sneaked in cheekily a change which defines a type more like idiomatic Go (I have an OCD :-))
92 lines
2.4 KiB
Go
92 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/sha1"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"launchpad.net/gommap"
|
|
|
|
"github.com/anacrolix/torrent/metainfo"
|
|
"github.com/anacrolix/torrent/mmap_span"
|
|
)
|
|
|
|
var (
|
|
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 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() {
|
|
flag.Parse()
|
|
summaryMap := make(map[bool][]int)
|
|
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...)...)
|
|
fileToMmap(filename, file.Length, devZero, mMapSpan)
|
|
}
|
|
log.Println(len(metaInfo.Info.Files))
|
|
} else {
|
|
fileToMmap(*dataPath, metaInfo.Info.Length, devZero, mMapSpan)
|
|
}
|
|
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 {
|
|
break
|
|
}
|
|
hash := sha1.New()
|
|
_, err := mMapSpan.WriteSectionTo(hash, int64(piece)*metaInfo.Info.PieceLength, metaInfo.Info.PieceLength)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
pieceValid = bytes.Equal(hash.Sum(nil), expectedHash)
|
|
summaryMap[pieceValid] = append(summaryMap[pieceValid], piece)
|
|
fmt.Println(piece, pieceValid)
|
|
}
|
|
if *summary {
|
|
verifySummary(summaryMap)
|
|
}
|
|
}
|