nightmaremail

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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 }