summaryrefslogtreecommitdiff
path: root/src/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/buffer.c391
1 files changed, 204 insertions, 187 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 75bd59b..34aeefb 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -34,21 +34,23 @@
#define BUFFER_HEAD(x) (x)->head
#define BUFFER_TAIL(x) (x)->tail
-struct bufline_s {
- unsigned char *string; /* the actual string of data */
- struct bufline_s *next; /* pointer to next in linked list */
- size_t length; /* length of the string of data */
- size_t pos; /* start sending from this offset */
+struct bufline_s
+{
+ unsigned char *string; /* the actual string of data */
+ struct bufline_s *next; /* pointer to next in linked list */
+ size_t length; /* length of the string of data */
+ size_t pos; /* start sending from this offset */
};
/*
* The buffer structure points to the beginning and end of the buffer list
* (and includes the total size)
*/
-struct buffer_s {
- struct bufline_s *head; /* top of the buffer */
- struct bufline_s *tail; /* bottom of the buffer */
- size_t size; /* total size of the buffer */
+struct buffer_s
+{
+ struct bufline_s *head; /* top of the buffer */
+ struct bufline_s *tail; /* bottom of the buffer */
+ size_t size; /* total size of the buffer */
};
/*
@@ -57,155 +59,158 @@ struct buffer_s {
* data buffer on the heap, delete it because you now have TWO copies.
*/
static struct bufline_s *
-makenewline(unsigned char *data, size_t length)
+makenewline (unsigned char *data, size_t length)
{
- struct bufline_s *newline;
+ struct bufline_s *newline;
- assert(data != NULL);
- assert(length > 0);
+ assert (data != NULL);
+ assert (length > 0);
- if (!(newline = safemalloc(sizeof(struct bufline_s))))
- return NULL;
+ if (!(newline = safemalloc (sizeof (struct bufline_s))))
+ return NULL;
- if (!(newline->string = safemalloc(length))) {
- safefree(newline);
- return NULL;
- }
+ if (!(newline->string = safemalloc (length)))
+ {
+ safefree (newline);
+ return NULL;
+ }
- memcpy(newline->string, data, length);
+ memcpy (newline->string, data, length);
- newline->next = NULL;
- newline->length = length;
+ newline->next = NULL;
+ newline->length = length;
- /* Position our "read" pointer at the beginning of the data */
- newline->pos = 0;
+ /* Position our "read" pointer at the beginning of the data */
+ newline->pos = 0;
- return newline;
+ return newline;
}
/*
* Free the allocated buffer line
*/
static void
-free_line(struct bufline_s *line)
+free_line (struct bufline_s *line)
{
- assert(line != NULL);
+ assert (line != NULL);
- if (!line)
- return;
+ if (!line)
+ return;
- if (line->string)
- safefree(line->string);
+ if (line->string)
+ safefree (line->string);
- safefree(line);
+ safefree (line);
}
/*
* Create a new buffer
*/
struct buffer_s *
-new_buffer(void)
+new_buffer (void)
{
- struct buffer_s *buffptr;
+ struct buffer_s *buffptr;
- if (!(buffptr = safemalloc(sizeof(struct buffer_s))))
- return NULL;
+ if (!(buffptr = safemalloc (sizeof (struct buffer_s))))
+ return NULL;
- /*
- * Since the buffer is initially empty, set the HEAD and TAIL
- * pointers to NULL since they can't possibly point anywhere at the
- * moment.
- */
- BUFFER_HEAD(buffptr) = BUFFER_TAIL(buffptr) = NULL;
- buffptr->size = 0;
+ /*
+ * Since the buffer is initially empty, set the HEAD and TAIL
+ * pointers to NULL since they can't possibly point anywhere at the
+ * moment.
+ */
+ BUFFER_HEAD (buffptr) = BUFFER_TAIL (buffptr) = NULL;
+ buffptr->size = 0;
- return buffptr;
+ return buffptr;
}
/*
* Delete all the lines in the buffer and the buffer itself
*/
void
-delete_buffer(struct buffer_s *buffptr)
+delete_buffer (struct buffer_s *buffptr)
{
- struct bufline_s *next;
+ struct bufline_s *next;
- assert(buffptr != NULL);
+ assert (buffptr != NULL);
- while (BUFFER_HEAD(buffptr)) {
- next = BUFFER_HEAD(buffptr)->next;
- free_line(BUFFER_HEAD(buffptr));
- BUFFER_HEAD(buffptr) = next;
- }
+ while (BUFFER_HEAD (buffptr))
+ {
+ next = BUFFER_HEAD (buffptr)->next;
+ free_line (BUFFER_HEAD (buffptr));
+ BUFFER_HEAD (buffptr) = next;
+ }
- safefree(buffptr);
+ safefree (buffptr);
}
/*
* Return the current size of the buffer.
*/
size_t
-buffer_size(struct buffer_s *buffptr)
+buffer_size (struct buffer_s *buffptr)
{
- return buffptr->size;
+ return buffptr->size;
}
/*
* Push a new line on to the end of the buffer.
*/
int
-add_to_buffer(struct buffer_s *buffptr, unsigned char *data, size_t length)
+add_to_buffer (struct buffer_s *buffptr, unsigned char *data, size_t length)
{
- struct bufline_s *newline;
-
- assert(buffptr != NULL);
- assert(data != NULL);
- assert(length > 0);
-
- /*
- * Sanity check here. A buffer with a non-NULL head pointer must
- * have a size greater than zero, and vice-versa.
- */
- if (BUFFER_HEAD(buffptr) == NULL)
- assert(buffptr->size == 0);
- else
- assert(buffptr->size > 0);
-
- /*
- * Make a new line so we can add it to the buffer.
- */
- if (!(newline = makenewline(data, length)))
- return -1;
-
- if (buffptr->size == 0)
- BUFFER_HEAD(buffptr) = BUFFER_TAIL(buffptr) = newline;
- else {
- BUFFER_TAIL(buffptr)->next = newline;
- BUFFER_TAIL(buffptr) = newline;
- }
-
- buffptr->size += length;
-
- return 0;
+ struct bufline_s *newline;
+
+ assert (buffptr != NULL);
+ assert (data != NULL);
+ assert (length > 0);
+
+ /*
+ * Sanity check here. A buffer with a non-NULL head pointer must
+ * have a size greater than zero, and vice-versa.
+ */
+ if (BUFFER_HEAD (buffptr) == NULL)
+ assert (buffptr->size == 0);
+ else
+ assert (buffptr->size > 0);
+
+ /*
+ * Make a new line so we can add it to the buffer.
+ */
+ if (!(newline = makenewline (data, length)))
+ return -1;
+
+ if (buffptr->size == 0)
+ BUFFER_HEAD (buffptr) = BUFFER_TAIL (buffptr) = newline;
+ else
+ {
+ BUFFER_TAIL (buffptr)->next = newline;
+ BUFFER_TAIL (buffptr) = newline;
+ }
+
+ buffptr->size += length;
+
+ return 0;
}
/*
* Remove the first line from the top of the buffer
*/
static struct bufline_s *
-remove_from_buffer(struct buffer_s *buffptr)
+remove_from_buffer (struct buffer_s *buffptr)
{
- struct bufline_s *line;
+ struct bufline_s *line;
- assert(buffptr != NULL);
- assert(BUFFER_HEAD(buffptr) != NULL);
+ assert (buffptr != NULL);
+ assert (BUFFER_HEAD (buffptr) != NULL);
- line = BUFFER_HEAD(buffptr);
- BUFFER_HEAD(buffptr) = line->next;
+ line = BUFFER_HEAD (buffptr);
+ BUFFER_HEAD (buffptr) = line->next;
- buffptr->size -= line->length;
+ buffptr->size -= line->length;
- return line;
+ return line;
}
/*
@@ -214,61 +219,69 @@ remove_from_buffer(struct buffer_s *buffptr)
*/
#define READ_BUFFER_SIZE (1024 * 2)
ssize_t
-read_buffer(int fd, struct buffer_s * buffptr)
+read_buffer (int fd, struct buffer_s * buffptr)
{
- ssize_t bytesin;
- unsigned char *buffer;
-
- assert(fd >= 0);
- assert(buffptr != NULL);
-
- /*
- * Don't allow the buffer to grow larger than MAXBUFFSIZE
- */
- if (buffptr->size >= MAXBUFFSIZE)
- return 0;
-
- buffer = safemalloc(READ_BUFFER_SIZE);
- if (!buffer) {
- return -ENOMEM;
- }
-
- bytesin = read(fd, buffer, READ_BUFFER_SIZE);
-
- if (bytesin > 0) {
- if (add_to_buffer(buffptr, buffer, bytesin) < 0) {
- log_message(LOG_ERR,
- "readbuff: add_to_buffer() error.");
- bytesin = -1;
- }
- } else {
- if (bytesin == 0) {
- /* connection was closed by client */
- bytesin = -1;
- } else {
- switch (errno) {
+ ssize_t bytesin;
+ unsigned char *buffer;
+
+ assert (fd >= 0);
+ assert (buffptr != NULL);
+
+ /*
+ * Don't allow the buffer to grow larger than MAXBUFFSIZE
+ */
+ if (buffptr->size >= MAXBUFFSIZE)
+ return 0;
+
+ buffer = safemalloc (READ_BUFFER_SIZE);
+ if (!buffer)
+ {
+ return -ENOMEM;
+ }
+
+ bytesin = read (fd, buffer, READ_BUFFER_SIZE);
+
+ if (bytesin > 0)
+ {
+ if (add_to_buffer (buffptr, buffer, bytesin) < 0)
+ {
+ log_message (LOG_ERR, "readbuff: add_to_buffer() error.");
+ bytesin = -1;
+ }
+ }
+ else
+ {
+ if (bytesin == 0)
+ {
+ /* connection was closed by client */
+ bytesin = -1;
+ }
+ else
+ {
+ switch (errno)
+ {
#ifdef EWOULDBLOCK
- case EWOULDBLOCK:
+ case EWOULDBLOCK:
#else
# ifdef EAGAIN
- case EAGAIN:
+ case EAGAIN:
# endif
#endif
- case EINTR:
- bytesin = 0;
- break;
- default:
- log_message(LOG_ERR,
- "readbuff: recv() error \"%s\" on file descriptor %d",
- strerror(errno), fd);
- bytesin = -1;
- break;
- }
- }
- }
-
- safefree(buffer);
- return bytesin;
+ case EINTR:
+ bytesin = 0;
+ break;
+ default:
+ log_message (LOG_ERR,
+ "readbuff: recv() error \"%s\" on file descriptor %d",
+ strerror (errno), fd);
+ bytesin = -1;
+ break;
+ }
+ }
+ }
+
+ safefree (buffer);
+ return bytesin;
}
/*
@@ -276,53 +289,57 @@ read_buffer(int fd, struct buffer_s * buffptr)
* Takes a connection and returns the number of bytes written.
*/
ssize_t
-write_buffer(int fd, struct buffer_s * buffptr)
+write_buffer (int fd, struct buffer_s * buffptr)
{
- ssize_t bytessent;
- struct bufline_s *line;
-
- assert(fd >= 0);
- assert(buffptr != NULL);
-
- if (buffptr->size == 0)
- return 0;
-
- /* Sanity check. It would be bad to be using a NULL pointer! */
- assert(BUFFER_HEAD(buffptr) != NULL);
- line = BUFFER_HEAD(buffptr);
-
- bytessent =
- send(fd, line->string + line->pos, line->length - line->pos,
- MSG_NOSIGNAL);
-
- if (bytessent >= 0) {
- /* bytes sent, adjust buffer */
- line->pos += bytessent;
- if (line->pos == line->length)
- free_line(remove_from_buffer(buffptr));
- return bytessent;
- } else {
- switch (errno) {
+ ssize_t bytessent;
+ struct bufline_s *line;
+
+ assert (fd >= 0);
+ assert (buffptr != NULL);
+
+ if (buffptr->size == 0)
+ return 0;
+
+ /* Sanity check. It would be bad to be using a NULL pointer! */
+ assert (BUFFER_HEAD (buffptr) != NULL);
+ line = BUFFER_HEAD (buffptr);
+
+ bytessent =
+ send (fd, line->string + line->pos, line->length - line->pos,
+ MSG_NOSIGNAL);
+
+ if (bytessent >= 0)
+ {
+ /* bytes sent, adjust buffer */
+ line->pos += bytessent;
+ if (line->pos == line->length)
+ free_line (remove_from_buffer (buffptr));
+ return bytessent;
+ }
+ else
+ {
+ switch (errno)
+ {
#ifdef EWOULDBLOCK
- case EWOULDBLOCK:
+ case EWOULDBLOCK:
#else
# ifdef EAGAIN
- case EAGAIN:
+ case EAGAIN:
# endif
#endif
- case EINTR:
- return 0;
- case ENOBUFS:
- case ENOMEM:
- log_message(LOG_ERR,
- "writebuff: write() error [NOBUFS/NOMEM] \"%s\" on file descriptor %d",
- strerror(errno), fd);
- return 0;
- default:
- log_message(LOG_ERR,
- "writebuff: write() error \"%s\" on file descriptor %d",
- strerror(errno), fd);
- return -1;
- }
- }
+ case EINTR:
+ return 0;
+ case ENOBUFS:
+ case ENOMEM:
+ log_message (LOG_ERR,
+ "writebuff: write() error [NOBUFS/NOMEM] \"%s\" on file descriptor %d",
+ strerror (errno), fd);
+ return 0;
+ default:
+ log_message (LOG_ERR,
+ "writebuff: write() error \"%s\" on file descriptor %d",
+ strerror (errno), fd);
+ return -1;
+ }
+ }
}