netstring_get.c (1385B)
1 /* ISC license. */ 2 3 #include <errno.h> 4 5 #include <skalibs/types.h> 6 #include <skalibs/allreadwrite.h> 7 #include <skalibs/bytestr.h> 8 #include <skalibs/buffer.h> 9 #include <skalibs/stralloc.h> 10 #include <skalibs/netstring.h> 11 #include <skalibs/posixishard.h> 12 13 int netstring_okeof (buffer *b, size_t w) 14 { 15 return (errno == EPIPE) && !w && buffer_isempty(b) ? (errno = 0, 1) : 0 ; 16 } 17 18 int netstring_get (buffer *b, stralloc *sa, size_t *state) 19 { 20 if (!*state) 21 { 22 size_t n ; 23 size_t len ; 24 char buf[SIZE_FMT] ; 25 if (b->c.a < SIZE_FMT+1) return (errno = EINVAL, -1) ; 26 for (;;) 27 { 28 ssize_t r ; 29 len = buffer_getnofill(b, buf, SIZE_FMT) ; 30 n = byte_chr(buf, len, ':') ; /* XXX: accepts :, as a valid netstring */ 31 if (n >= SIZE_FMT) 32 { 33 buffer_unget(b, len) ; 34 return (errno = EPROTO, -1) ; 35 } 36 if (n < len) break ; 37 buffer_unget(b, len) ; 38 r = sanitize_read(buffer_fill(b)) ; 39 if (r <= 0) return r ; 40 } 41 buffer_unget(b, len - n - 1) ; 42 if (!n || n != size_scan(buf, &len)) return (errno = EPROTO, -1) ; 43 if (!stralloc_readyplus(sa, len + 1)) return -1 ; 44 *state = len + 1 ; 45 } 46 { 47 size_t w = 0 ; 48 int r = buffer_getall(b, sa->s + sa->len, *state, &w) ; 49 sa->len += w ; 50 *state -= w ; 51 if (r <= 0) return r ; 52 } 53 return (sa->s[--sa->len] == ',') ? 1 : (errno = EPROTO, -1) ; 54 }