netstrings.c (2177B)
1 #include "netstrings.h" 2 #include "fmt.h" 3 #include "unistd.h" 4 5 signed char ns_getlength (_BUFFER *bio, unsigned long long *length) 6 { 7 char ch; 8 9 if (length == NULL) return NS_INVAL; 10 *length = 0; 11 for (;;) { 12 _BUFFER_GET(bio, &ch, 1); 13 if (ch == ':') return NS_SUCCESS; // *length is already set correctly 14 if (ch < '0') return NS_PROTOCOL; 15 if (ch > '9') return NS_PROTOCOL; // ':', which is > '9', is already covered 16 if (*length > 4294967296) return NS_TOOMUCH; // Netstrings longer than 4GiB are valid, but we have no interest in processing them here. 17 // should be if (*length > 9223372036854775808) return NS_TOOMUCH; // which is 2^63, but at that point it's simply not rational. No-one has 2 to the 63 space available to them. 18 *length = 10 * (*length) + (ch - '0'); 19 } 20 } 21 22 signed char ns_getcomma (_BUFFER *bio) 23 { 24 // This can effectively be verbatim from qmtpd. 25 char ch; 26 _BUFFER_GET(bio, &ch, 1); 27 return (ch == ',')? NS_SUCCESS : NS_PROTOCOL; 28 } 29 30 // it is expected that ns_put will only be used for strings of up to size_t. 31 // if you somehow find a way to exceed that, good job. we won't help you. 32 signed char ns_put (_BUFFER *bio, char *buf, unsigned long long length) 33 { 34 char buf2[100]; 35 unsigned long long blen = 0; 36 blen += fmt_ulonglong(buf2+blen, length); 37 blen += fmt_str(buf2+blen, ":"); 38 buf2[blen] = 0; 39 if (_BUFFER_PUT(bio, buf2, blen) == -1) return NS_BIOERR; 40 // buf2 is now irrelevant 41 if (_BUFFER_PUT(bio, buf, length) == -1) return NS_BIOERR; 42 if (_BUFFER_PUT(bio, ",", 1) == -1) return NS_BIOERR; 43 return NS_SUCCESS; // writing may still yet fail 44 } 45 46 // it is expected that ns_put will only be used for strings of up to size_t. 47 // if you somehow find a way to exceed that, good job. we won't help you. 48 signed char ns_print (int fd, char *buf, unsigned long long length) 49 { 50 char buf2[100]; 51 unsigned long long blen = 0; 52 blen += fmt_ulonglong(buf2+blen, length); 53 blen += fmt_str(buf2+blen, ":"); 54 buf2[blen] = 0; 55 if (write(fd, buf2, blen) == -1) return NS_BIOERR; 56 // buf2 is now irrelevant 57 if (write(fd, buf, length) == -1) return NS_BIOERR; 58 if (write(fd, ",", 1) == -1) return NS_BIOERR; 59 return NS_SUCCESS; // writing may still yet fail 60 }