ip/torrent: create announce-list torrents

front
cinap_lenrek 2012-04-15 19:26:04 +02:00
parent 0d961d31bc
commit 53511a9097
1 changed files with 41 additions and 15 deletions

View File

@ -10,11 +10,11 @@ typedef struct Stats Stats;
struct Dict struct Dict
{ {
char typ; // i, d, s, l
Dict *val; Dict *val;
Dict *next; Dict *next;
char *start, *end; char *start, *end;
int len; int len;
char typ; // i, d, s, l
char str[]; char str[];
}; };
@ -746,7 +746,7 @@ Hfmt(Fmt *f)
} }
int int
mktorrent(int fd, char *url) mktorrent(int fd, Dict *alist)
{ {
uchar *b, h[20]; uchar *b, h[20];
Dir *d; Dir *d;
@ -771,7 +771,14 @@ mktorrent(int fd, char *url)
break; break;
} }
print("d"); print("d");
print("8:announce%ld:%s", strlen(url), url); print("8:announce%ld:%s", strlen(alist->str), alist->str);
if(alist->next){
print("13:announce-listl");
print("l%ld:%se", strlen(alist->str), alist->str);
for(alist = alist->next; alist; alist = alist->next)
print("l%ld:%se", strlen(alist->str), alist->str);
print("e");
}
print("4:info"); print("4:info");
print("d"); print("d");
print("4:name%ld:%s", strlen(d->name), d->name); print("4:name%ld:%s", strlen(d->name), d->name);
@ -858,24 +865,40 @@ usage(void)
exits("usage"); exits("usage");
} }
Dict*
scons(char *s, Dict *t)
{
Dict *l;
if(s == nil)
return t;
for(l = t; l; l = l->next)
if(cistrcmp(l->str, s) == 0)
return t;
l = mallocz(sizeof(*l) + strlen(s)+1, 1);
l->next = t;
strcpy(l->str, s);
return l;
}
void void
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
int sflag, pflag, vflag, cflag, fd, i, n; int sflag, pflag, vflag, cflag, fd, i, n;
Dict *info, *torrent, *d; Dict *alist, *info, *torrent, *d, *l;
char *p, *s, *e, *url; char *p, *s, *e;
File **fp, *f; File **fp, *f;
vlong len; vlong len;
fmtinstall('H', Hfmt); fmtinstall('H', Hfmt);
url = nil; alist = nil;
sflag = pflag = vflag = cflag = 0; sflag = pflag = vflag = cflag = 0;
ARGBEGIN { ARGBEGIN {
case 'm': case 'm':
mntweb = EARGF(usage()); mntweb = EARGF(usage());
break; break;
case 't': case 't':
url = EARGF(usage()); alist = scons(EARGF(usage()), alist);
break; break;
case 's': case 's':
sflag = 1; sflag = 1;
@ -901,15 +924,21 @@ main(int argc, char *argv[])
if((fd = open(*argv, OREAD)) < 0) if((fd = open(*argv, OREAD)) < 0)
sysfatal("open: %r"); sysfatal("open: %r");
if(cflag){ if(cflag){
if(url == nil) if(alist == nil)
url = deftrack; alist = scons(deftrack, alist);
if(mktorrent(fd, url) < 0) if(mktorrent(fd, alist) < 0)
sysfatal("%r"); sysfatal("%r");
exits(0); exits(0);
} }
if((n = readall(fd, &p)) <= 0) if((n = readall(fd, &p)) <= 0)
sysfatal("read torrent: %r"); sysfatal("read torrent: %r");
bparse(p, p+n, &torrent); bparse(p, p+n, &torrent);
alist = scons(dstr(dlook(torrent, "announce")), alist);
for(d = dlook(torrent, "announce-list"); d && d->typ == 'l'; d = d->next)
for(l = d->val; l && l->typ == 'l'; l = l->next)
alist = scons(dstr(l->val), alist);
if(alist == nil)
sysfatal("no trackers in torrent");
if((d = info = dlook(torrent, "info")) == nil) if((d = info = dlook(torrent, "info")) == nil)
sysfatal("no meta info in torrent"); sysfatal("no meta info in torrent");
for(s = e = d->start; d && d->typ == 'd'; d = d->next) for(s = e = d->start; d && d->typ == 'd'; d = d->next)
@ -993,11 +1022,8 @@ main(int argc, char *argv[])
for(i=8; i<sizeof(peerid); i++) for(i=8; i<sizeof(peerid); i++)
peerid[i] = nrand(10)+'0'; peerid[i] = nrand(10)+'0';
server(); server();
tracker(url); for(; alist; alist = alist->next)
tracker(dstr(dlook(torrent, "announce"))); tracker(alist->str);
for(d = dlook(torrent, "announce-list"); d && d->typ == 'l'; d = d->next)
if(d->val && d->val->typ == 'l')
tracker(dstr(d->val->val));
while(waitpid() != -1) while(waitpid() != -1)
; ;
break; break;