torrentd

simple torrent daemon
git clone git://git.2f30.org/torrentd
Log | Files | Refs | LICENSE

commit 5278f8f077195cc3da3dacee5b376cdd8e811bb6
parent 8375c04910e59654bc4fee4fbe8a820e1d3f839d
Author: sin <sin@2f30.org>
Date:   Thu, 17 Dec 2015 12:38:07 +0000

Do not kill the process if a parsing error occurs

Diffstat:
Mben.c | 55+++++++++++++++++++++++++++++++++++++------------------
1 file changed, 37 insertions(+), 18 deletions(-)

diff --git a/ben.c b/ben.c @@ -16,6 +16,7 @@ #include <ctype.h> #include <err.h> +#include <setjmp.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -23,6 +24,17 @@ #include "sbtd.h" +static char *parse(char *, char *, struct ben **); + +static jmp_buf savesp; + +static void +error(char *msg) +{ + fprintf(stderr, "%s\n", msg); + longjmp(savesp, 1); +} + static char * parsestr(char *s, char *e, struct ben **b) { @@ -32,11 +44,11 @@ parsestr(char *s, char *e, struct ben **b) for (p = s; p != e && isdigit((int)*p); p++) len = len * 10 + *p - '0'; if (p == e) - goto eof; + error("bad string"); if (*p != ':') - errx(1, "expected :, got %c", *p); + error("expected ':' in string"); if (p + len >= e) - goto eof; + error("bad string"); p += len; *b = emalloc(sizeof(**b)); (*b)->type = 's'; @@ -45,8 +57,6 @@ parsestr(char *s, char *e, struct ben **b) (*b)->end = p + 1; (*b)->len = len; return p; -eof: - errx(1, "bad string"); } static char * @@ -57,9 +67,9 @@ parseint(char *s, char *e, struct ben **b) int isneg = 0, iszero = 0; if (*p != 'i') - errx(1, "expected integer"); + error("expected integer"); if (++p == e) - errx(1, "bad integer"); + error("bad integer"); switch (*p) { case '-': @@ -77,16 +87,16 @@ parseint(char *s, char *e, struct ben **b) v = 0; while (1) { if (++p == e) - errx(1, "bad integer"); + error("bad integer"); if (*p == 'e' || iszero) { if (*p != 'e') - errx(1, "0 not followed by e"); + error("0 not followed by e"); break; } if (isneg && *p == '0') - errx(1, "i-0 is invalid"); + error("i-0 is invalid"); if (!isdigit((int)*p)) - errx(1, "unexpected char in integer %c", *p); + error("unexpected char in integer"); v = v * 10 + *p - '0'; } @@ -108,10 +118,10 @@ parsedl(char *s, char *e, struct ben **b) memset(&head, 0, sizeof(head)); if (*p != 'd' && *p != 'l') - errx(1, "expected dictionary or list"); + error("expected dictionary or list"); while (1) { if (++p == e) - errx(1, "bad dictionary or list"); + error("bad dictionary or list"); if (*p == 'e') break; bp->next = emalloc(sizeof(*bp)); @@ -122,11 +132,11 @@ parsedl(char *s, char *e, struct ben **b) p = parsestr(p, e, &bp->k); p++; } - p = bdecode(p, e, &bp->v); + p = parse(p, e, &bp->v); bp->next = NULL; } if (*p != 'e') - errx(1, "expected terminator"); + error("expected terminator"); *b = head.next; if (!head.next) { @@ -141,8 +151,8 @@ parsedl(char *s, char *e, struct ben **b) return p; } -char * -bdecode(char *s, char *e, struct ben **b) +static char * +parse(char *s, char *e, struct ben **b) { if (s == e) return s; @@ -156,11 +166,20 @@ bdecode(char *s, char *e, struct ben **b) break; default: if (!isdigit((int)*s)) - errx(1, "unknown type %c", *s); + error("unknown type"); return parsestr(s, e, b); } } +char * +bdecode(char *s, char *e, struct ben **b) +{ + *b = NULL; + if (!setjmp(savesp)) + return parse(s, e, b); + return NULL; +} + void bencode(char **buf, size_t *n, struct ben *b) {