Ejemplo n.º 1
0
func main() {
	flag.Parse()
	cl, err := torrent.NewClient(nil)
	if err != nil {
		log.Fatalf("error creating client: %s", err)
	}
	wg := sync.WaitGroup{}
	for _, arg := range flag.Args() {
		t, err := cl.AddMagnet(arg)
		if err != nil {
			log.Fatalf("error adding magnet to client: %s", err)
		}
		wg.Add(1)
		go func() {
			defer wg.Done()
			<-t.GotInfo()
			mi := t.Metainfo()
			t.Drop()
			f, err := os.Create(mi.Info.Name + ".torrent")
			if err != nil {
				log.Fatalf("error creating torrent metainfo file: %s", err)
			}
			defer f.Close()
			err = bencode.NewEncoder(f).Encode(mi)
			if err != nil {
				log.Fatalf("error writing torrent metainfo file: %s", err)
			}
		}()
	}
	wg.Wait()
}
Ejemplo n.º 2
0
func (b *Batch) write_torrent(w io.Writer) error {
	var td MetaInfo

	// Either announce or node lists are allowed - not both
	if len(b.announce_list) != 0 {
		td.Announce = b.announce_list[0][0]
		if len(b.announce_list) != 1 || len(b.announce_list[0]) != 1 {
			td.AnnounceList = b.announce_list
		}
	}

	if len(b.node_list) != 0 {
		td.Nodes = b.node_list
	}

	td.CreationDate = b.creation_date.Unix()
	td.Comment = b.comment
	td.CreatedBy = b.created_by
	td.Encoding = b.encoding
	switch {
	case len(b.urls) == 0:
	case len(b.urls) == 1:
		td.URLList = b.urls[0]
	default:
		td.URLList = b.urls
	}

	td.Info.PieceLength = b.piece_length
	td.Info.Pieces = b.pieces
	if b.name == "" {
		td.Info.Name = b.default_name
	} else {
		td.Info.Name = b.name
	}
	if len(b.files) == 1 {
		td.Info.Length = b.files[0].size
	} else {
		td.Info.Files = make([]FileInfo, len(b.files))
		for i, f := range b.files {
			td.Info.Files[i] = FileInfo{
				Path:   f.splitpath,
				Length: f.size,
			}
		}
	}
	td.Info.Private = b.private

	e := bencode.NewEncoder(w)
	return e.Encode(&td)
}
Ejemplo n.º 3
0
// Encode to bencoded form.
func (mi *MetaInfo) Write(w io.Writer) error {
	return bencode.NewEncoder(w).Encode(mi)
}
Ejemplo n.º 4
0
func (d *delugeProcess) Start() error {
	cmd := exec.Command("deluged", "-d", "-i", d.ip.String())
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err := cmd.Start()
	if err != nil {
		return err
	}

	d.Process = cmd.Process

	//starts a super minimal bittorrent tracker that only returns peers
	go func() {
		torrents := map[string]map[string]peer{}
		log.Printf("Starting tracker on '%s'...", d.trackerBind)
		err = http.ListenAndServe(d.trackerBind, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

			//map[ipv6:[fe80::226:bbff:fe0a:e12b] info_hash:[?0FA??c??N???] left:[100000000] key:[B22982B1] event:[started] numwant:[200] compact:[1] no_peer_id:[1] peer_id:[-UM1870-{??qCzVB<ur] port:[40959] uploaded:[0] downloaded:[0] corrupt:[0]]
			err := r.ParseForm()
			if err != nil {
				log.Printf("Failed to parse announce form data: %s", err)
				return
			}

			host, port, err := net.SplitHostPort(r.RemoteAddr)
			if err != nil {
				log.Printf("Failed to parse remote host and port: %s", err)
				return
			}

			if r.Form.Get("peer_id") == "" {
				//@todo sometimes peer_id is empty?
				return
			}

			//add announcing peer to peerlist of torrent
			log.Printf("Torrent Client (peer_id: '%s', compact: %s) announces from %s:%s, port set to %s for info_hash '%x'", r.Form.Get("peer_id"), r.Form.Get("compact"), host, port, r.Form.Get("port"), r.Form.Get("info_hash"))
			peerlist, ok := torrents[r.Form.Get("info_hash")]
			if !ok {
				peerlist = map[string]peer{}
				torrents[r.Form.Get("info_hash")] = peerlist
			}

			peerlist[r.Form.Get("peer_id")] = peer{
				PeerID: r.Form.Get("peer_id"),
				IP:     host,
				Port:   r.Form.Get("port"),
			}

			peers := []peer{}
			for _, p := range peerlist {
				peers = append(peers, p)
			}

			if r.Form.Get("compact") == "1" {
				buff := bytes.NewBuffer(nil)
				err = d.writeCompactPeers(buff, peers)
				if err != nil {
					log.Printf("Error: %s", err)
					return
				}

				log.Printf("compact: '% x'", buff.Bytes())
				data := struct {
					Peers []byte `bencode:"peers"`
				}{
					Peers: buff.Bytes(),
				}

				//encode response
				log.Printf("Returning announce with: %+v", data)
				w.Header().Set("Content-Type", "text/plain")
				enc := bencode.NewEncoder(w)
				err = enc.Encode(data)
				if err != nil {
					log.Printf("Failed to bencode: %s", err)
					return
				}

			} else {
				data := struct {
					Peers []peer `bencode:"peers"`
				}{
					Peers: peers,
				}

				//encode response
				log.Printf("Returning announce with: %+v", data)
				w.Header().Set("Content-Type", "text/plain")
				enc := bencode.NewEncoder(w)
				err = enc.Encode(data)
				if err != nil {
					log.Printf("Failed to bencode: %s", err)
					return
				}
			}

		}))

		log.Printf("Tracker exited")
		if err != nil {
			log.Printf("Tracker failed: %s", err)
		}
	}()

	log.Printf("Torrent files can be downloaded at: '%s'", d.filesBind)
	go func() {
		log.Fatal(http.ListenAndServe(d.filesBind, http.FileServer(http.Dir(d.torrentPath))))
	}()

	return nil
}