nightmaremail

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

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 }