commit 416746160f4cd148dba78c07594dab3a8622475e
parent da29d1879a28ed9c71c3c558dad418c9fa31f9ab
Author: sin <sin@2f30.org>
Date: Sat, 19 Dec 2015 11:33:38 +0000
Use unloadtorrent() for unwinding
Should work given that everything is using ecalloc().
Diffstat:
M | torrent.c | | | 61 | ++++++++++++++++++++++--------------------------------------- |
1 file changed, 22 insertions(+), 39 deletions(-)
diff --git a/torrent.c b/torrent.c
@@ -64,40 +64,40 @@ loadtorrent(char *f)
t = ecalloc(1, sizeof(*t));
if (readfile(f, &t->buf, &t->buflen) < 0) {
warnx("failed to read %s", f);
- goto err0;
+ goto fail;
}
if (!bdecode(t->buf, t->buf + t->buflen, &t->ben)) {
warnx("failed to decode %s", f);
- goto err1;
+ goto fail;
}
t->info = dlookstr(t->ben, "info");
if (!t->info) {
warnx("no info dictionary in %s", f);
- goto err2;
+ goto fail;
}
t->pieces = dlookstr(t->info, "pieces");
if (!t->pieces) {
warnx("no pieces field in %s", f);
- goto err2;
+ goto fail;
}
if (t->pieces->len % 20) {
warnx("incorrect pieces length in %s", f);
- goto err2;
+ goto fail;
}
if ((tmp = dlookstr(t->ben, "announce-list")) && tmp->len) {
if (tmp->type != 'l') {
warnx("announce-list must be of type list");
- goto err3;
+ goto fail;
}
t->announcers = ecalloc(tmp->len, sizeof(struct announce));
for (i = 0; tmp; tmp = tmp->next, i++, t->nannouncers++) {
if (tmp->v->type != 'l') {
warnx("announce-list item must be of type list");
- goto err3;
+ goto fail;
}
if (!tmp->v->len)
continue;
@@ -105,7 +105,7 @@ loadtorrent(char *f)
for (a = tmp->v, j = 0; a; a = a->next, j++, t->announcers[i].len++) {
if (a->v->type != 's') {
warnx("announce item must be of type string");
- goto err3;
+ goto fail;
}
t->announcers[i].urls[j] = bstr2str(a->v);
}
@@ -118,22 +118,22 @@ loadtorrent(char *f)
t->announcers[0].urls[0] = bstr2str(tmp);
} else {
warnx("no announce field in %s", f);
- goto err2;
+ goto fail;
}
if (!dlookstr(t->info, "piece length")) {
warnx("no piece length field in %s", f);
- goto err2;
+ goto fail;
}
t->piecelen = dlookstr(t->info, "piece length")->i;
if (t->piecelen <= 0) {
warnx("piecelen is <= 0 in %s", f);
- goto err2;
+ goto fail;
}
if (!dlookstr(t->info, "name")) {
warnx("no filename field in %s", f);
- goto err2;
+ goto fail;
}
t->filename = bstr2str(dlookstr(t->info, "name"));
@@ -141,22 +141,22 @@ loadtorrent(char *f)
if ((files = dlookstr(t->info, "files"))) {
if (files->type != 'l') {
warnx("files must be of type list");
- goto err2;
+ goto fail;
}
t->files = ecalloc(files->len, sizeof(struct file));
for (file = files; file; file = file->next, t->nfiles++) {
if (!(length = dlookstr(file->v, "length"))) {
warnx("no length field in %s", f);
- goto err3;
+ goto fail;
}
if (length->type != 'i') {
warnx("length must be of type integer");
- goto err3;
+ goto fail;
}
if (length->i < 0) {
warnx("length is < 0 in %s", f);
- goto err3;
+ goto fail;
}
totallen += length->i;
t->files[t->nfiles].len = length->i;
@@ -170,7 +170,7 @@ loadtorrent(char *f)
for (tmp = path, pathlen = 0; tmp; tmp = tmp->next) {
if (tmp->v->type != 's') {
warnx("path item must be of type string");
- goto err2;
+ goto fail;
}
pathlen += tmp->v->len + 1;
}
@@ -186,15 +186,15 @@ loadtorrent(char *f)
} else {
if (!(length = dlookstr(t->info, "length"))) {
warnx("no length field in %s", f);
- goto err2;
+ goto fail;
}
if (length->type != 'i') {
warnx("length must be of type integer");
- goto err2;
+ goto fail;
}
if (length->i < 0) {
warnx("length is < 0 in %s", f);
- goto err2;
+ goto fail;
}
t->nfiles = 1;
t->files = ecalloc(1, sizeof(struct file));
@@ -211,25 +211,8 @@ loadtorrent(char *f)
return t;
-err3:
- i = t->nannouncers;
- while (i--) {
- j = t->announcers[i].len;
- while (j--)
- free(t->announcers[i].urls[j]);
- free(t->announcers[i].urls);
- }
- free(t->announcers);
- while (t->nfiles--)
- free(t->files[t->nfiles].path);
- free(t->files);
-err2:
- free(t->filename);
- bfree(t->ben);
-err1:
- free(t->buf);
-err0:
- free(t);
+fail:
+ unloadtorrent(t);
return NULL;
}