예제 #1
0
파일: main.go 프로젝트: hoffoo/lstorrent
func lstorrent(path string) {
	fmt.Printf("%s\n", path)
	defer fmt.Printf("\n")
	f, err := os.OpenFile(path, os.O_RDONLY, 0600)

	if err != nil {
		fmt.Printf("Failed opening file: ", err)
		return
	}
	defer f.Close()

	datb, err := bencode.Decode(f)
	if err != nil {
		fmt.Printf("Failed decoding:", err)
		return
	}

	tor_info, ok := datb["info"].(map[string]interface{})
	if !ok {

	}

	// first look for files key
	files, ok := tor_info["files"].([]interface{})
	if ok {
		for _, v := range files {
			file := v.(map[string]interface{})
			path := file["path"].([]interface{})[0].(string)
			fmt.Printf("%s\n", path)
		}

		return // finished printing multifile torrent
	}

	// second look for name key
	file, ok := tor_info["name"].(string)
	if ok {
		fmt.Printf("%s\n", file)
		return
	}

	fmt.Printf("couldnt find files in torrent: %s", path)
}
예제 #2
0
파일: parser.go 프로젝트: bbucko/torrot
//New creates new torrent
func New(fileName string) *MetainfoFile {
	file, err := os.Open(fileName)
	if err != nil {
		log.Print("Opening file err: ", err)
		return nil
	}
	defer file.Close()

	encodedTorrent, err := bencode.Decode(file)
	if err != nil {
		log.Print("Decoding torrent err: ", err)
		return nil
	}

	encodedInfo := encodedTorrent["info"].(map[string]interface{})

	//Parse File element
	files := []fileDict{}
	if length, ok := encodedInfo["length"].(int64); ok {
		//Single File Mode
		files = append(files, fileDict{
			length: length,
			path:   []string{encodedInfo["name"].(string)},
			md5sum: getFromMapWithDefault(encodedTorrent, "md5sum", "").(string),
		})
	} else {
		//Multi File Mode
		for _, encodedFileElement := range encodedInfo["files"].([]interface{}) {
			encodedFile := encodedFileElement.(map[string]interface{})

			encodedPath := []string{}
			for _, encodedPathElement := range encodedFile["path"].([]interface{}) {
				encodedPath = append(encodedPath, encodedPathElement.(string))
			}
			files = append(files, fileDict{
				length: encodedFile["length"].(int64),
				path:   encodedPath,
				md5sum: getFromMapWithDefault(encodedTorrent, "md5sum", "").(string),
			})
		}
	}

	//Parse Announce List (arrays of arrays of strings
	announceList := [][]string{}
	if encodedAnnounceList, ok := encodedTorrent["announce-list"]; ok {
		for _, encodedAnnounceListElement := range encodedAnnounceList.([]interface{}) {
			announceListElement := []string{}
			for _, encodedAnnounceListElementElement := range encodedAnnounceListElement.([]interface{}) {
				announceListElement = append(announceListElement, encodedAnnounceListElementElement.(string))
			}
			announceList = append(announceList, announceListElement)
		}
	}

	return &MetainfoFile{
		info: infoDict{
			name:        encodedInfo["name"].(string),
			pieceLength: encodedInfo["piece length"].(int64),
			pieces:      encodedInfo["pieces"].(string),

			files: files,
		},
		announce:     encodedTorrent["announce"].(string),
		announceList: announceList,
		comment:      getFromMapWithDefault(encodedTorrent, "comment", "").(string),
		private:      getFromMapWithDefault(encodedTorrent, "private", false).(bool),
	}
}
예제 #3
0
func (torrent *Torrent) open(filename string) error {
	file, err := os.Open(filename)
	if err != nil {
		return err
	}
	defer file.Close()

	data, err := bencode.Decode(file)
	if err != nil {
		return err
	}

	if announceLists, ok := data["announce-list"].([]interface{}); ok {
		for _, announceList := range announceLists {
			for _, announceURL := range announceList.([]interface{}) {
				torrent.parseTrackerURL(announceURL.(string))
			}
		}
	} else {
		torrent.parseTrackerURL(data["announce"].(string))
	}

	if comment, ok := data["comment"]; ok {
		torrent.comment = comment.(string)
	}

	info := data["info"].(map[string]interface{})
	torrent.name = info["name"].(string)
	torrent.pieceLength = info["piece length"].(int64)

	infoHash := sha1.Sum(bencode.Encode(info))

	// Set handshake
	var buffer bytes.Buffer
	buffer.WriteByte(19) // length of the string "BitTorrent Protocol"
	buffer.WriteString("BitTorrent protocol")
	buffer.WriteString("\x00\x00\x00\x00\x00\x00\x00\x00") // reserved
	buffer.Write(infoHash[:])
	buffer.Write(client.peerID)
	torrent.handshake = buffer.Bytes()

	// Set pieces
	pieces := info["pieces"].(string)
	for i := 0; i < len(pieces); i += 20 {
		torrent.pieces = append(torrent.pieces, TorrentPiece{
			hash: pieces[i : i+20],
		})
	}

	if err := os.Mkdir("Downloads", 0700); err != nil && !os.IsExist(err) {
		return err
	}

	cwd, err := os.Getwd()
	if err != nil {
		return err
	}

	base := filepath.Join(cwd, "Downloads")

	// Set files
	if files, exists := info["files"]; exists {
		dirName := filepath.Join("Downloads", info["name"].(string))
		if err := torrent.validatePath(base, dirName); err != nil {
			return err
		}

		base := filepath.Join(cwd, dirName)

		for _, v := range files.([]interface{}) {
			v := v.(map[string]interface{})
			torrent.totalSize += v["length"].(int64)
		}

		// Multiple files
		var begin int64
		for k, v := range files.([]interface{}) {
			v := v.(map[string]interface{})

			// Set up directory structure
			pathList := v["path"].([]interface{})
			pathElements := []string{dirName}
			for i := 0; i < len(pathList)-1; i++ {
				pathElements = append(pathElements, pathList[i].(string))
			}

			path := filepath.Join(pathElements...)
			fullPath := filepath.Join(path, pathList[len(pathList)-1].(string))
			if err := torrent.validatePath(base, fullPath); err != nil {
				return err
			}

			if len(path) != 0 {
				if err := os.MkdirAll(path, 0700); err != nil {
					return err
				}
			}

			length := v["length"].(int64)

			file, err := os.OpenFile(fullPath, os.O_RDWR, 0600)
			if err == nil {
				torrent.findCompletedPieces(file, begin, length, k)
				file.Close()
			}

			torrent.files = append(torrent.files, File{fullPath, begin, length})
			begin += length
		}
	} else {
		// Single file
		fileName := filepath.Join("Downloads", info["name"].(string))
		if err := torrent.validatePath(base, fileName); err != nil {
			return err
		}

		length := info["length"].(int64)
		torrent.totalSize = length

		file, err := os.OpenFile(fileName, os.O_RDWR, 0600)
		if err == nil {
			torrent.findCompletedPieces(file, 0, length, 0)
			file.Close()
		}
		torrent.files = []File{{fileName, 0, length}}
	}
	return nil
}