Index: buffer.c =================================================================== RCS file: /home/chris/vcvs/repos/tpop3d/buffer.c,v retrieving revision 1.6 diff -u -r1.6 buffer.c --- buffer.c 6 Jan 2003 19:01:17 -0000 1.6 +++ buffer.c 5 Nov 2003 18:30:14 -0000 @@ -12,7 +12,9 @@ #include #include +#include #include +#include #include "buffer.h" #include "util.h" @@ -34,6 +36,38 @@ xfree(B); } +/* buffer_make_contiguous BUFFER + * Makes the available data in BUFFER contiguous, so that it can be returned + * by a single call to buffer_get_consume_ptr. */ +void buffer_make_contiguous(buffer B) { + size_t a; + char *newbuf; + + assert(B); + + a = buffer_available(B); + if (!a || (size_t)B->get + a <= B->len) + /* Nothing to do. */ + return; + + /* + * v (get + a) % len + * ,---------------------------------------------. + * |XXXXXXXXXXXXXXXXX| |XXXXXXXXXXX| + * | (get + a) % len | | len - get | + * |XXXXXXXXXXXXXXXXX| |XXXXXXXXXXX| + * `---------------------------------------------' + * ^ 0 ^ get + */ + newbuf = xmalloc(B->len); + memcpy(newbuf, B->buf + B->get, B->len - B->get); + memcpy(newbuf + B->len - B->get, B->buf, (B->get + a) % B->len); + xfree(B->buf); + B->buf = newbuf; + B->get = 0; + B->put = a; +} + /* buffer_get_consume_ptr BUFFER SLEN * Consume some available data in BUFFER, returning a pointer to the data and * recording the number of bytes consumed in SLEN. This may be less than the @@ -50,7 +84,7 @@ *slen = 0; return NULL; } - if (B->get + a > B->len) + if ((size_t)B->get + a > B->len) a = B->len - B->get; p = B->buf + B->get; *slen = a; @@ -101,27 +135,30 @@ * This uses a Boyer-Moore search, but we can't just reuse memstr because we * may have to search across the end of the buffer. */ char *buffer_consume_to_mark(buffer B, const char *mark, const size_t mlen, char *str, size_t *slen) { - int skip[256], k; - size_t a; + size_t skip[256], a; + int k; assert(B); + assert(mlen > 0 && mlen <= (size_t)INT_MAX); if ((a = buffer_available(B)) < mlen) return NULL; + assert(a <= (size_t)INT_MAX); + /* Oh dear. Should special-case the mlen == 1 case, since it's the only * one we use.... */ for (k = 0; k < 256; ++k) skip[k] = mlen; - for (k = 0; k < mlen - 1; ++k) skip[(unsigned char)mark[k]] = mlen - k - 1; + for (k = 0; k < (int)mlen - 1; ++k) skip[(unsigned char)mark[k]] = mlen - k - 1; - for (k = mlen - 1; k < a; k += skip[(unsigned char)mark[k]]) { + for (k = (int)mlen - 1; k < (int)a; k += skip[(unsigned char)mark[k]]) { int i, j; - for (j = mlen - 1, i = k; j >= 0 && B->buf[(B->get + i) % B->len] == mark[j]; j--) i--; + for (j = (int)mlen - 1, i = k; j >= 0 && B->buf[(B->get + i) % B->len] == mark[j]; j--) i--; if (j == -1) { /* Have found the mark at location i + 1. */ i += 1 + mlen; /* account for mark and terminating null */ - if (!str || *slen < i + 1) - str = xrealloc(str, i + 1); - *slen = i + 1; + if (!str || *slen < (size_t)i + 1) + str = xrealloc(str, (size_t)i + 1); + *slen = (size_t)i + 1; for (j = 0; j < i; ++j) str[j] = B->buf[(B->get + j) % B->len]; str[j] = 0; @@ -150,7 +187,7 @@ B->buf = newbuf; B->len = newlen; B->get = 0; - B->put = a; + B->put = (off_t)a; } } Index: buffer.h =================================================================== RCS file: /home/chris/vcvs/repos/tpop3d/buffer.h,v retrieving revision 1.2 diff -u -r1.2 buffer.h --- buffer.h 10 Nov 2002 02:34:27 -0000 1.2 +++ buffer.h 5 Nov 2003 18:30:14 -0000 @@ -21,11 +21,12 @@ /* buffer_available BUFFER * Return the number of bytes of data available to consume from BUFFER. This * is a macro which may evaluate BUFFER more than once. */ -#define buffer_available(B) (((B)->put + (B)->len - (B)->get) % (B)->len) +#define buffer_available(B) ((size_t)(((B)->put + (B)->len - (B)->get) % (B)->len)) /* buffer.c */ buffer buffer_new(const size_t len); void buffer_delete(buffer B); +void buffer_make_contiguous(buffer B); char *buffer_get_consume_ptr(buffer B, size_t *slen); void buffer_consume_bytes(buffer B, const size_t num); char *buffer_consume_all(buffer B, char *str, size_t *slen); Index: ioabs_tls.c =================================================================== RCS file: /home/chris/vcvs/repos/tpop3d/ioabs_tls.c,v retrieving revision 1.12 diff -u -r1.12 ioabs_tls.c --- ioabs_tls.c 30 Dec 2002 16:22:45 -0000 1.12 +++ ioabs_tls.c 5 Nov 2003 18:30:14 -0000 @@ -152,6 +152,23 @@ return IOABS_ERROR; } +static void dump(const char *s, size_t l) { + const char *p; + fprintf(stderr, ">>>"); + for (p = s; p < s + l; ++p) { + if (*p < 32) + switch(*p) { + case '\t': fprintf(stderr, "\\t"); break; + case '\r': fprintf(stderr, "\\r"); break; + case '\n': fprintf(stderr, "\\n"); break; + default: fprintf(stderr, "\\x%02x", *p); + } + else fprintf(stderr, "%c", (int)*p); + } + fprintf(stderr, "<<<\n"); +} + + /* ioabs_tls_immediate_write CONNECTION BUFFER COUNT * Attempt to write COUNT bytes from BUFFER to CONNECTION. Returns the number * of bytes written on success, IOABS_WOULDBLOCK if the write would block, and @@ -160,8 +177,8 @@ static ssize_t ioabs_tls_immediate_write(connection c, const void *buf, size_t count) { int n, e; struct ioabs_tls *io; - io = (struct ioabs_tls*)c->io; + io = (struct ioabs_tls*)c->io; if (count == 0) return 0; /* otherwise can't distinguish this case... */ if (io->read_blocked_on_write) return IOABS_WOULDBLOCK; @@ -176,6 +193,7 @@ } e = ERR_get_error(); + switch (SSL_get_error(io->ssl, n)) { case SSL_ERROR_WANT_READ: io->write_blocked_on_read = 1; @@ -228,7 +246,7 @@ * Post-select handling for TLS, with its complicated logic. */ static int ioabs_tls_post_select(connection c, fd_set *readfds, fd_set *writefds, fd_set *exceptfds) { int ret = 0, R = 0; - ssize_t n; + ssize_t n, wtotal; int canread, canwrite; struct ioabs_tls *io; io = (struct ioabs_tls*)c->io; @@ -305,9 +323,11 @@ } /* Write from the buffer to the connection, if necessary. */ - if (((!io->write_blocked_on_read && !io->read_blocked_on_write && canwrite) || (io->write_blocked_on_read && canread)) && buffer_available(c->wrb) > 0) { + if (((!io->write_blocked_on_read && !io->read_blocked_on_write && canwrite) + || (io->write_blocked_on_read && canread)) + && (wtotal = buffer_available(c->wrb)) > 0) { io->write_blocked_on_read = 0; - n = 1; + buffer_make_contiguous(c->wrb); do { char *w; size_t wlen;