diff options
author | cinap_lenrek <cinap_lenrek@centraldogma> | 2011-10-25 14:09:41 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@centraldogma> | 2011-10-25 14:09:41 +0200 |
commit | d8bde8f7b35078dd07ee76bc493031aac315fcbb (patch) | |
tree | 8c9cd209dbf792a3d5d889f213734f956ac1c0e1 /sys | |
parent | 45cc898e4a626cc67312629ae6fe2d25e6cfd733 (diff) |
torrent: fix \0 escaping bug, add -c option to create new torrents
Diffstat (limited to 'sys')
-rw-r--r-- | sys/man/1/torrent | 47 | ||||
-rw-r--r-- | sys/src/cmd/ip/torrent.c | 79 |
2 files changed, 107 insertions, 19 deletions
diff --git a/sys/man/1/torrent b/sys/man/1/torrent index cf423d074..e4a215762 100644 --- a/sys/man/1/torrent +++ b/sys/man/1/torrent @@ -5,21 +5,21 @@ torrent \- bittorrent client .B ip/torrent [ .B -d -] -[ +] [ .B -v -] -[ +] [ .B -p -] -[ +] [ .B -m .I mtpt -] -[ +] [ +.B -t +.I url +] [ .B -s -] -[ +] [ +.B -c +] [ .I file ] .SH DESCRIPTION @@ -36,7 +36,24 @@ Before files can be transmitted, a torrent-file needs to be created describing the pieces of the files and other meta-data like network addresses of the trackers. .PP -.I Torrent +This is done with the +.B -c +option. If provided, +.I torrent +reads the file given at the final +.I file +argument (or standard-input when omited) and writes +a torrent file to standard-output and exits. +A tracker +.I url +should be given with the +.B -t +option in that case. +.PP +Without the +.B -c +option, +.I torrent downloads the files that are described in the torrent-file given by the .I file @@ -74,7 +91,13 @@ To monitor the download progress, the option can be given to cause the completed and total number of pieces written as a line of text to standard-output in one second intervals. -.SH EXAMPLE +.SH EXAMPLES +Create new torrent file +.EX +ip/torrent -t http://exodus.desync.com/announce \\ + -c 9atom.iso >9atom.torrent +.EE +.LP Download the latest iso file of the distribution .EX cd /tmp diff --git a/sys/src/cmd/ip/torrent.c b/sys/src/cmd/ip/torrent.c index 140e92ab0..f4d8bc1de 100644 --- a/sys/src/cmd/ip/torrent.c +++ b/sys/src/cmd/ip/torrent.c @@ -46,9 +46,10 @@ enum { MAXIO = 16*1024, }; -int debug, sflag, pflag, vflag; +int debug; int killgroup = -1; int port = 6881; +char *deftrack = "http://exodus.desync.com/announce"; char *mntweb = "/mnt/web"; uchar infohash[20]; uchar peerid[20]; @@ -736,7 +737,7 @@ Hfmt(Fmt *f) else e = s + strlen((char*)s); for(; s < e; s++) - if(fmtprint(f, ((*s >= '0' && *s <= '9') || + if(fmtprint(f, *s && ((*s >= '0' && *s <= '9') || (*s >= 'a' && *s <= 'z') || (*s >= 'A' && *s <= 'Z') || strchr(".-_~", *s)) ? "%c" : "%%%.2x", *s) < 0) @@ -745,6 +746,55 @@ Hfmt(Fmt *f) } int +mktorrent(int fd, char *url) +{ + uchar *b, h[20]; + Dir *d; + int n; + + if((d = dirfstat(fd)) == nil) + return -1; + if(d->qid.type == QTDIR){ + free(d); + werrstr("file is a directory"); + return -1; + } + if(d->length == 0){ + free(d); + werrstr("empty file"); + return -1; + } + blocksize = 1024*1024; + npieces = (d->length + blocksize-1) / blocksize; + print("d"); + print("8:announce%ld:%s", strlen(url), url); + print("4:info"); + print("d"); + print("4:name%ld:%s", strlen(d->name), d->name); + print("6:lengthi%llde", d->length); + print("12:piece lengthi%de", blocksize); + print("6:pieces%d:", npieces*sizeof(h)); + free(d); + b = malloc(blocksize); + while((n = readn(fd, b, blocksize)) > 0){ + sha1(b, n, h, nil); + if(write(1, h, sizeof(h)) != sizeof(h)){ + free(b); + return -1; + } + npieces--; + } + free(b); + if(npieces){ + werrstr("read failed: %r"); + return -1; + } + print("e"); + print("e"); + return 0; +} + +int mkdirs(char *s) { char *p; @@ -800,25 +850,29 @@ killnote(void *, char *) void usage(void) { - fprint(2, "usage: %s [ -vsdp ] [ -m mtpt ] [ torrentfile ]\n", argv0); + fprint(2, "usage: %s [ -vsdpc ] [ -m mtpt ] [ -t url ] [ file ]\n", argv0); exits("usage"); } void main(int argc, char *argv[]) { + int sflag, pflag, vflag, cflag, fd, i, n; Dict *info, *torrent, *d; + char *p, *s, *e, *url; File **fp, *f; - char *p, *s, *e; - int fd, i, n; vlong len; fmtinstall('H', Hfmt); - + url = nil; + sflag = pflag = vflag = cflag = 0; ARGBEGIN { case 'm': mntweb = EARGF(usage()); break; + case 't': + url = EARGF(usage()); + break; case 's': sflag = 1; break; @@ -828,6 +882,9 @@ main(int argc, char *argv[]) case 'v': vflag = 1; break; + case 'c': + cflag = 1; + break; case 'd': debug++; break; @@ -838,7 +895,14 @@ main(int argc, char *argv[]) fd = 0; if(*argv) if((fd = open(*argv, OREAD)) < 0) - sysfatal("open torrent: %r"); + sysfatal("open: %r"); + if(cflag){ + if(url == nil) + url = deftrack; + if(mktorrent(fd, url) < 0) + sysfatal("%r"); + exits(0); + } if((n = readall(fd, &p)) <= 0) sysfatal("read torrent: %r"); bparse(p, p+n, &torrent); @@ -925,6 +989,7 @@ main(int argc, char *argv[]) for(i=8; i<sizeof(peerid); i++) peerid[i] = nrand(10)+'0'; server(); + tracker(url); tracker(dstr(dlook(torrent, "announce"))); for(d = dlook(torrent, "announce-list"); d && d->typ == 'l'; d = d->next) if(d->val && d->val->typ == 'l') |