17 fusefs "bazil.org/fuse/fs"
18 _ "github.com/anacrolix/envpprof"
20 "github.com/anacrolix/torrent"
21 "github.com/anacrolix/torrent/fs"
22 "github.com/anacrolix/torrent/util/dirwatch"
26 torrentPath = flag.String("torrentPath", func() string {
27 _user, err := user.Current()
31 return filepath.Join(_user.HomeDir, ".config/transmission/torrents")
32 }(), "torrent files in this location describe the contents of the mounted filesystem")
33 downloadDir = flag.String("downloadDir", "", "location to save torrent data")
34 mountDir = flag.String("mountDir", "", "location the torrent contents are made available")
36 disableTrackers = flag.Bool("disableTrackers", false, "disables trackers")
37 testPeer = flag.String("testPeer", "", "the address for a test peer")
38 readaheadBytes = flag.Int64("readaheadBytes", 10*1024*1024, "bytes to readahead in each torrent from the last read piece")
39 listenAddr = flag.String("listenAddr", ":6882", "incoming connection address")
41 testPeerAddr *net.TCPAddr
44 func resolveTestPeerAddr() {
49 testPeerAddr, err = net.ResolveTCPAddr("tcp4", *testPeer)
55 func exitSignalHandlers(fs *torrentfs.TorrentFS) {
56 c := make(chan os.Signal)
57 signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
61 err := fuse.Unmount(*mountDir)
68 func addTestPeer(client *torrent.Client) {
69 for _, t := range client.Torrents() {
70 if testPeerAddr != nil {
71 if err := t.AddPeers([]torrent.Peer{{
73 Port: testPeerAddr.Port,
84 os.Stderr.WriteString("one does not simply pass positional args\n")
88 os.Stderr.WriteString("y u no specify mountpoint?\n")
91 log.SetFlags(log.LstdFlags | log.Lshortfile)
92 conn, err := fuse.Mount(*mountDir)
96 defer fuse.Unmount(*mountDir)
97 // TODO: Think about the ramifications of exiting not due to a signal.
99 client, err := torrent.NewClient(&torrent.Config{
100 DataDir: *downloadDir,
101 DisableTrackers: *disableTrackers,
102 // DownloadStrategy: torrent.NewResponsiveDownloadStrategy(*readaheadBytes),
103 ListenAddr: *listenAddr,
104 NoUpload: true, // Ensure that uploads are responsive.
106 http.DefaultServeMux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
107 client.WriteStatus(w)
109 dw, err := dirwatch.New(*torrentPath)
114 for ev := range dw.Events {
117 if ev.TorrentFilePath != "" {
118 _, err := client.AddTorrentFromFile(ev.TorrentFilePath)
120 log.Printf("error adding torrent to client: %s", err)
122 } else if ev.MagnetURI != "" {
123 _, err := client.AddMagnet(ev.MagnetURI)
125 log.Printf("error adding magnet: %s", err)
128 case dirwatch.Removed:
129 for _, t := range client.Torrents() {
130 if t.InfoHash != ev.InfoHash {
139 resolveTestPeerAddr()
140 fs := torrentfs.New(client)
141 go exitSignalHandlers(fs)
145 time.Sleep(10 * time.Second)
149 if err := fusefs.Serve(conn, fs); err != nil {
153 if err := conn.MountError; err != nil {