Multiple file metainfo mode support in cmd tools

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 :-))
This commit is contained in:
Milos Gajdos 2015-05-16 13:23:33 +01:00
parent dfada8514e
commit e6e0b227da
4 changed files with 54 additions and 34 deletions

View File

@ -26,6 +26,9 @@ func init() {
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() {

View File

@ -16,16 +16,40 @@ import (
)
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 @@ func main() {
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 @@ func main() {
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)
}
}

View File

@ -980,11 +980,13 @@ func bootstrapAddrs(nodeAddrs []string) (addrs []*net.UDPAddr, err error) {
}
}
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")

View File

@ -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 {