Cleaned up the source so that the internal structure is no exposed by the

buffer.h header.
This commit is contained in:
Robert James Kaes 2000-09-11 23:41:32 +00:00
parent 55185db499
commit b7f7599d76
2 changed files with 104 additions and 198 deletions

View File

@ -1,4 +1,4 @@
/* $Id: buffer.c,v 1.2 2000-03-31 20:09:19 rjkaes Exp $ /* $Id: buffer.c,v 1.3 2000-09-11 23:41:32 rjkaes Exp $
* *
* The buffer used in each connection is a linked list of lines. As the lines * The buffer used in each connection is a linked list of lines. As the lines
* are read in and written out the buffer expands and contracts. Basically, * are read in and written out the buffer expands and contracts. Basically,
@ -21,21 +21,35 @@
* General Public License for more details. * General Public License for more details.
*/ */
#ifdef HAVE_CONFIG_H
#include <defines.h>
#endif
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <assert.h>
#include "utils.h"
#include "log.h"
#include "tinyproxy.h" #include "tinyproxy.h"
#include "buffer.h" #include "buffer.h"
#include "log.h"
#include "utils.h"
#define BUFFER_HEAD(x) (((struct buffer_s *)(x))->head)
#define BUFFER_TAIL(x) (((struct buffer_s *)(x))->tail)
struct bufline_s {
unsigned char *string; /* the actual string of data */
struct bufline_s *next; /* pointer to next in linked list */
unsigned int length; /* length of the string of data */
unsigned int pos; /* start sending from this offset */
};
struct buffer_s {
struct bufline_s *head; /* top of the buffer */
struct bufline_s *tail; /* bottom of the buffer */
unsigned int size; /* total size of the buffer */
};
/*
* Return the size of the supplied buffer.
*/
unsigned int buffer_size(struct buffer_s *buffptr)
{
return buffptr->size;
}
/* /*
* Take a string of data and a length and make a new line which can be added * Take a string of data and a length and make a new line which can be added
@ -45,10 +59,7 @@ static struct bufline_s *makenewline(unsigned char *data, unsigned int length)
{ {
struct bufline_s *newline; struct bufline_s *newline;
assert(data); if (!(newline = malloc(sizeof(struct bufline_s))))
assert(length > 0);
if (!(newline = xmalloc(sizeof(struct bufline_s))))
return NULL; return NULL;
newline->string = data; newline->string = data;
@ -59,52 +70,10 @@ static struct bufline_s *makenewline(unsigned char *data, unsigned int length)
return newline; return newline;
} }
/*
* Create a new buffer
*/
struct buffer_s *new_buffer(void)
{
struct buffer_s *buffptr;
if (!(buffptr = xmalloc(sizeof(struct buffer_s))))
return NULL;
buffptr->head = buffptr->tail = NULL;
buffptr->size = 0;
buffptr->working_string = NULL;
buffptr->working_length = 0;
return buffptr;
}
/*
* Delete all the lines in the buffer and the buffer itself
*/
void delete_buffer(struct buffer_s *buffptr)
{
struct bufline_s *next;
assert(buffptr);
while (buffer_head(buffptr)) {
next = buffer_head(buffptr)->next;
free_line(buffer_head(buffptr));
buffer_head(buffptr) = next;
}
buffer_head(buffptr) = NULL;
buffer_tail(buffptr) = NULL;
buffptr->working_length = 0;
safefree(buffptr->working_string);
safefree(buffptr);
}
/* /*
* Free the allocated buffer line * Free the allocated buffer line
*/ */
void free_line(struct bufline_s *line) static void free_line(struct bufline_s *line)
{ {
if (!line) if (!line)
return; return;
@ -116,111 +85,81 @@ void free_line(struct bufline_s *line)
safefree(line); safefree(line);
} }
/*
* Create a new buffer
*/
struct buffer_s *new_buffer(void)
{
struct buffer_s *buffptr;
if (!(buffptr = malloc(sizeof(struct buffer_s))))
return NULL;
buffptr->head = buffptr->tail = NULL;
buffptr->size = 0;
return buffptr;
}
/*
* Delete all the lines in the buffer and the buffer itself
*/
void delete_buffer(struct buffer_s *buffptr)
{
struct bufline_s *next;
while (BUFFER_HEAD(buffptr)) {
next = BUFFER_HEAD(buffptr)->next;
free_line(BUFFER_HEAD(buffptr));
BUFFER_HEAD(buffptr) = next;
}
BUFFER_HEAD(buffptr) = NULL;
BUFFER_TAIL(buffptr) = NULL;
safefree(buffptr);
}
/* /*
* Push a new line on to the end of the buffer * Push a new line on to the end of the buffer
*/ */
struct bufline_s *push_buffer(struct buffer_s *buffptr, unsigned char *data, static int add_to_buffer(struct buffer_s *buffptr, unsigned char *data,
unsigned int length) unsigned int length)
{ {
struct bufline_s *newline; struct bufline_s *newline;
assert(buffptr);
assert(data);
assert(length > 0);
if (!(newline = makenewline(data, length))) if (!(newline = makenewline(data, length)))
return NULL; return -1;
if (!buffer_head(buffptr) && !buffer_tail(buffptr)) if (!BUFFER_HEAD(buffptr) && !BUFFER_TAIL(buffptr))
buffer_head(buffptr) = buffer_tail(buffptr) = newline; BUFFER_HEAD(buffptr) = BUFFER_TAIL(buffptr) = newline;
else else
buffer_tail(buffptr) = (buffer_tail(buffptr)->next = newline); BUFFER_TAIL(buffptr) = (BUFFER_TAIL(buffptr)->next = newline);
buffptr->size += length; buffptr->size += length;
return newline; return 0;
}
/*
* Pop a buffer line off the end of the buffer
*/
struct bufline_s *pop_buffer(struct buffer_s *buffptr)
{
struct bufline_s *line, *newend;
assert(buffptr);
if (buffer_head(buffptr) == buffer_tail(buffptr)) {
line = buffer_head(buffptr);
buffer_head(buffptr) = buffer_tail(buffptr) = NULL;
buffptr->size = 0;
return line;
}
line = buffer_tail(buffptr);
newend = buffer_head(buffptr);
while (newend->next != line && newend->next)
newend = newend->next;
buffer_tail(buffptr) = newend;
buffptr->size -= line->length;
return line;
}
/*
* Unshift a buffer line from the top of the buffer (meaning add a new line
* to the top of the buffer)
*/
struct bufline_s *unshift_buffer(struct buffer_s *buffptr, unsigned char *data,
unsigned int length)
{
struct bufline_s *newline;
assert(buffptr);
assert(data);
assert(length > 0);
if (!(newline = makenewline(data, length)))
return NULL;
if (!buffer_head(buffptr) && buffer_tail(buffptr)) {
buffer_head(buffptr) = buffer_tail(buffptr) = newline;
} else {
newline->next = buffer_head(buffptr);
buffer_head(buffptr) = newline;
if (!buffer_tail(buffptr))
buffer_tail(buffptr) = newline;
}
buffptr->size += length;
return newline;
} }
/* /*
* Shift a line off the top of the buffer (remove the line from the top of * Shift a line off the top of the buffer (remove the line from the top of
* the buffer) * the buffer)
*/ */
struct bufline_s *shift_buffer(struct buffer_s *buffptr) static struct bufline_s *remove_from_buffer(struct buffer_s *buffptr)
{ {
struct bufline_s *line; struct bufline_s *line;
assert(buffptr); if (!BUFFER_HEAD(buffptr) && !BUFFER_TAIL(buffptr)) {
line = BUFFER_HEAD(buffptr);
if (!buffer_head(buffptr) && !buffer_tail(buffptr)) { BUFFER_HEAD(buffptr) = BUFFER_TAIL(buffptr) = NULL;
line = buffer_head(buffptr);
buffer_head(buffptr) = buffer_tail(buffptr) = NULL;
buffptr->size = 0; buffptr->size = 0;
return line; return line;
} }
line = buffer_head(buffptr); line = BUFFER_HEAD(buffptr);
buffer_head(buffptr) = line->next; BUFFER_HEAD(buffptr) = line->next;
if (!buffer_head(buffptr)) if (!BUFFER_HEAD(buffptr))
buffer_tail(buffptr) = NULL; BUFFER_TAIL(buffptr) = NULL;
buffptr->size -= line->length; buffptr->size -= line->length;
@ -234,20 +173,25 @@ struct bufline_s *shift_buffer(struct buffer_s *buffptr)
int readbuff(int fd, struct buffer_s *buffptr) int readbuff(int fd, struct buffer_s *buffptr)
{ {
int bytesin; int bytesin;
unsigned char inbuf[BUFFER]; unsigned char inbuf[MAXBUFFSIZE];
unsigned char *buffer; unsigned char *buffer;
assert(fd >= 0); if (buffer_size(buffptr) >= MAXBUFFSIZE)
assert(buffptr); return 0;
bytesin = recv(fd, inbuf, BUFFER, 0); bytesin = read(fd, inbuf, MAXBUFFSIZE - buffer_size(buffptr));
if (bytesin > 0) { if (bytesin > 0) {
if (!(buffer = xmalloc(bytesin))) if (!(buffer = malloc(bytesin))) {
log(LOG_CRIT, "Could not allocate memory in readbuff() [%s:%d]", __FILE__, __LINE__);
return 0; return 0;
}
memcpy(buffer, inbuf, bytesin); memcpy(buffer, inbuf, bytesin);
push_buffer(buffptr, buffer, bytesin); if (add_to_buffer(buffptr, buffer, bytesin) < 0) {
return -1;
}
return bytesin; return bytesin;
} else if (bytesin == 0) { } else if (bytesin == 0) {
/* connection was closed by client */ /* connection was closed by client */
@ -263,10 +207,8 @@ int readbuff(int fd, struct buffer_s *buffptr)
#endif #endif
case EINTR: case EINTR:
return 0; return 0;
case ECONNRESET:
return -1;
default: default:
log("ERROR readbuff: recv (%s)", strerror(errno)); log(LOG_ERR, "readbuff: recv (%s)", strerror(errno));
return -1; return -1;
} }
} }
@ -279,19 +221,18 @@ int readbuff(int fd, struct buffer_s *buffptr)
int writebuff(int fd, struct buffer_s *buffptr) int writebuff(int fd, struct buffer_s *buffptr)
{ {
int bytessent; int bytessent;
struct bufline_s *line = buffer_head(buffptr); struct bufline_s *line = BUFFER_HEAD(buffptr);
assert(fd >= 0); if (buffer_size(buffptr) <= 0)
assert(buffptr); return 0;
bytessent = send(fd, line->string + line->pos, bytessent = write(fd, line->string + line->pos, line->length - line->pos);
(size_t) (line->length - line->pos), 0);
if (bytessent >= 0) { if (bytessent >= 0) {
/* bytes sent, adjust buffer */ /* bytes sent, adjust buffer */
line->pos += bytessent; line->pos += bytessent;
if (line->pos == line->length) if (line->pos == line->length)
free_line(shift_buffer(buffptr)); free_line(remove_from_buffer(buffptr));
return bytessent; return bytessent;
} else { } else {
switch (errno) { switch (errno) {
@ -302,12 +243,14 @@ int writebuff(int fd, struct buffer_s *buffptr)
case EAGAIN: case EAGAIN:
# endif # endif
#endif #endif
case ENOBUFS:
case EINTR: case EINTR:
return 0;
case ENOBUFS:
case ENOMEM: case ENOMEM:
log(LOG_ERR, "writebuff: send [NOBUFS/NOMEM] %s", strerror(errno));
return 0; return 0;
default: default:
log("ERROR writebuff: send (%s)", strerror(errno)); log(LOG_ERR, "writebuff: send (%s)", strerror(errno));
return -1; return -1;
} }
} }

View File

@ -1,4 +1,4 @@
/* $Id: buffer.h,v 1.2 2000-03-31 20:09:19 rjkaes Exp $ /* $Id: buffer.h,v 1.3 2000-09-11 23:41:32 rjkaes Exp $
* *
* See 'buffer.c' for a detailed description. * See 'buffer.c' for a detailed description.
* *
@ -15,50 +15,13 @@
* General Public License for more details. * General Public License for more details.
*/ */
#ifndef __BUFFER_H_ #ifndef _TINYPROXY_BUFFER_H_
#define __BUFFER_H_ 1 #define _TINYPROXY_BUFFER_H_
#define MAXBUFFSIZE 20480
struct bufline_s {
unsigned char *string; /* the actual string of data */
struct bufline_s *next; /* pointer to next in linked list */
unsigned int length; /* length of the string of data */
unsigned int pos; /* start sending from this offset */
};
struct buffer_s {
struct bufline_s *head; /* top of the buffer */
struct bufline_s *tail; /* bottom of the buffer */
unsigned long int size; /* total size of the buffer */
unsigned char *working_string; /* needed for building a new line incr. */
unsigned int working_length; /* length of working line */
};
#define buffer_head(x) (((struct buffer_s *)(x))->head)
#define buffer_tail(x) (((struct buffer_s *)(x))->tail)
#define buffer_size(x) (((struct buffer_s *)(x))->size)
/* Create and delete buffers */
extern struct buffer_s *new_buffer(void); extern struct buffer_s *new_buffer(void);
extern void delete_buffer(struct buffer_s *buffptr); extern void delete_buffer(struct buffer_s *buffptr);
extern unsigned int buffer_size(struct buffer_s *buffptr);
/* Operate on the end of the list */
extern struct bufline_s *push_buffer(struct buffer_s *buffptr,
unsigned char *data, unsigned int length);
extern struct bufline_s *pop_buffer(struct buffer_s *buffptr);
/* Operate on the head of the list */
extern struct bufline_s *unshift_buffer(struct buffer_s *buffptr,
unsigned char *data,
unsigned int length);
extern struct bufline_s *shift_buffer(struct buffer_s *buffptr);
/* Free a buffer line */
extern void free_line(struct bufline_s *line);
/* Read/Write the buffer to a socket */
extern int readbuff(int fd, struct buffer_s *buffptr); extern int readbuff(int fd, struct buffer_s *buffptr);
extern int writebuff(int fd, struct buffer_s *buffptr); extern int writebuff(int fd, struct buffer_s *buffptr);