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