summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/acl.c229
-rw-r--r--src/acl.h5
-rw-r--r--src/anonymous.c36
-rw-r--r--src/buffer.c340
-rw-r--r--src/buffer.h6
-rw-r--r--src/child.c553
-rw-r--r--src/child.h12
-rw-r--r--src/common.h12
-rw-r--r--src/conffile.c449
-rw-r--r--src/conffile.h4
-rw-r--r--src/conns.c168
-rw-r--r--src/conns.h98
-rw-r--r--src/daemon.c50
-rw-r--r--src/daemon.h4
-rw-r--r--src/filter.c282
-rw-r--r--src/filter.h6
-rw-r--r--src/hashmap.c526
-rw-r--r--src/hashmap.h36
-rw-r--r--src/heap.c127
-rw-r--r--src/heap.h16
-rw-r--r--src/htmlerror.c342
-rw-r--r--src/htmlerror.h9
-rw-r--r--src/http_message.c314
-rw-r--r--src/http_message.h15
-rw-r--r--src/log.c187
-rw-r--r--src/log.h6
-rw-r--r--src/network.c438
-rw-r--r--src/network.h6
-rw-r--r--src/reqs.c2697
-rw-r--r--src/sock.c302
-rw-r--r--src/sock.h10
-rw-r--r--src/stats.c171
-rw-r--r--src/stats.h12
-rw-r--r--src/text.c73
-rw-r--r--src/text.h6
-rw-r--r--src/tinyproxy.c547
-rw-r--r--src/tinyproxy.h108
-rw-r--r--src/utils.c296
-rw-r--r--src/utils.h4
-rw-r--r--src/vector.c166
-rw-r--r--src/vector.h22
41 files changed, 4452 insertions, 4238 deletions
diff --git a/src/acl.c b/src/acl.c
index e4941e4..bbfacc7 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -1,4 +1,4 @@
-/* $Id: acl.c,v 1.21 2005-07-12 17:39:43 rjkaes Exp $
+/* $Id: acl.c,v 1.22 2005-08-15 03:54:31 rjkaes Exp $
*
* This system handles Access Control for use of this daemon. A list of
* domains, or IP addresses (including IP blocks) are stored in a list
@@ -37,15 +37,15 @@ enum acl_type { ACL_STRING, ACL_NUMERIC };
* entry (like a domain name) or an IP entry.
*/
struct acl_s {
- acl_access_t access;
- enum acl_type type;
- union {
- char* string;
+ acl_access_t access;
+ enum acl_type type;
+ union {
+ char *string;
struct {
unsigned char octet[IPV6_LEN];
unsigned char mask[IPV6_LEN];
} ip;
- } address;
+ } address;
};
/*
@@ -65,11 +65,11 @@ static vector_t access_list = NULL;
int
insert_acl(char *location, acl_access_t access_type)
{
- struct acl_s acl;
- int i, ret, mask;
- char *p, ip_dst[IPV6_LEN];
+ struct acl_s acl;
+ int i, ret, mask;
+ char *p, ip_dst[IPV6_LEN];
- assert(location != NULL);
+ assert(location != NULL);
/*
* If the access list has not been set up, create it.
@@ -110,7 +110,7 @@ insert_acl(char *location, acl_access_t access_type)
*p = '\0';
if (full_inet_pton(location, ip_dst) <= 0)
return -1;
-
+
acl.type = ACL_NUMERIC;
memcpy(acl.address.ip.octet, ip_dst, IPV6_LEN);
@@ -119,7 +119,8 @@ insert_acl(char *location, acl_access_t access_type)
if (mask >= ((i + 1) * 8))
acl.address.ip.mask[i] = 0xff;
else
- acl.address.ip.mask[i] = 0xff << (8 - (mask - i * 8));
+ acl.address.ip.mask[i] =
+ 0xff << (8 - (mask - i * 8));
}
} else {
/* In all likelihood a string */
@@ -138,7 +139,6 @@ insert_acl(char *location, acl_access_t access_type)
return ret;
}
-
/*
* This function is called whenever a "string" access control is found in
* the ACL. From here we do both a text based string comparison, along with
@@ -149,72 +149,73 @@ insert_acl(char *location, acl_access_t access_type)
* -1 if no tests match, so skip
*/
static int
-acl_string_processing(struct acl_s* acl,
- const char* ip_address,
- const char* string_address)
+acl_string_processing(struct acl_s *acl,
+ const char *ip_address, const char *string_address)
{
- int match;
- struct addrinfo hints, *res, *ressave;
- size_t test_length, match_length;
- char ipbuf[512];
+ int match;
+ struct addrinfo hints, *res, *ressave;
+ size_t test_length, match_length;
+ char ipbuf[512];
assert(acl && acl->type == ACL_STRING);
assert(ip_address && strlen(ip_address) > 0);
assert(string_address && strlen(string_address) > 0);
- /*
- * If the first character of the ACL string is a period, we need to
- * do a string based test only; otherwise, we can do a reverse
- * lookup test as well.
- */
- if (acl->address.string[0] != '.') {
- memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- if (getaddrinfo(acl->address.string, NULL, &hints, &res) != 0)
- goto STRING_TEST;
-
- ressave = res;
-
- match = FALSE;
- do {
- get_ip_string(res->ai_addr, ipbuf, sizeof(ipbuf));
- if (strcmp(ip_address, ipbuf) == 0) {
- match = TRUE;
- break;
- }
- } while ((res = res->ai_next) != NULL);
-
- freeaddrinfo(ressave);
-
- if (match) {
- if (acl->access == ACL_DENY)
- return 0;
- else
- return 1;
- }
- }
-
-STRING_TEST:
- test_length = strlen(string_address);
- match_length = strlen(acl->address.string);
-
- /*
- * If the string length is shorter than AC string, return a -1 so
- * that the "driver" will skip onto the next control in the list.
- */
- if (test_length < match_length)
- return -1;
-
- if (strcasecmp(string_address + (test_length - match_length), acl->address.string) == 0) {
- if (acl->access == ACL_DENY)
- return 0;
- else
- return 1;
- }
-
- /* Indicate that no tests succeeded, so skip to next control. */
- return -1;
+ /*
+ * If the first character of the ACL string is a period, we need to
+ * do a string based test only; otherwise, we can do a reverse
+ * lookup test as well.
+ */
+ if (acl->address.string[0] != '.') {
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ if (getaddrinfo(acl->address.string, NULL, &hints, &res) != 0)
+ goto STRING_TEST;
+
+ ressave = res;
+
+ match = FALSE;
+ do {
+ get_ip_string(res->ai_addr, ipbuf, sizeof(ipbuf));
+ if (strcmp(ip_address, ipbuf) == 0) {
+ match = TRUE;
+ break;
+ }
+ } while ((res = res->ai_next) != NULL);
+
+ freeaddrinfo(ressave);
+
+ if (match) {
+ if (acl->access == ACL_DENY)
+ return 0;
+ else
+ return 1;
+ }
+ }
+
+ STRING_TEST:
+ test_length = strlen(string_address);
+ match_length = strlen(acl->address.string);
+
+ /*
+ * If the string length is shorter than AC string, return a -1 so
+ * that the "driver" will skip onto the next control in the list.
+ */
+ if (test_length < match_length)
+ return -1;
+
+ if (strcasecmp
+ (string_address + (test_length - match_length),
+ acl->address.string) == 0) {
+ if (acl->access == ACL_DENY)
+ return 0;
+ else
+ return 1;
+ }
+
+ /* Indicate that no tests succeeded, so skip to next control. */
+ return -1;
}
/*
@@ -226,30 +227,30 @@ STRING_TEST:
* -1 neither allowed nor denied.
*/
static int
-check_numeric_acl(const struct acl_s* acl, const char* ip)
+check_numeric_acl(const struct acl_s *acl, const char *ip)
{
- uint8_t addr[IPV6_LEN], x, y;
- int i;
+ uint8_t addr[IPV6_LEN], x, y;
+ int i;
assert(acl && acl->type == ACL_NUMERIC);
assert(ip && strlen(ip) > 0);
- if (full_inet_pton(ip, &addr) <= 0) return -1;
+ if (full_inet_pton(ip, &addr) <= 0)
+ return -1;
- for (i = 0; i != IPV6_LEN; ++i) {
+ for (i = 0; i != IPV6_LEN; ++i) {
x = addr[i] & acl->address.ip.mask[i];
y = acl->address.ip.octet[i] & acl->address.ip.mask[i];
/* If x and y don't match, the IP addresses don't match */
if (x != y)
return 0;
- }
+ }
- /* The addresses match, return the permission */
- return (acl->access == ACL_ALLOW);
+ /* The addresses match, return the permission */
+ return (acl->access == ACL_ALLOW);
}
-
/*
* Checks whether file descriptor is allowed.
*
@@ -258,48 +259,50 @@ check_numeric_acl(const struct acl_s* acl, const char* ip)
* 0 if denied
*/
int
-check_acl(int fd, const char* ip, const char* host)
+check_acl(int fd, const char *ip, const char *host)
{
- struct acl_s* acl;
- int perm;
+ struct acl_s *acl;
+ int perm;
int i;
- assert(fd >= 0);
- assert(ip != NULL);
- assert(host != NULL);
+ assert(fd >= 0);
+ assert(ip != NULL);
+ assert(host != NULL);
- /*
- * If there is no access list allow everything.
- */
- if (!access_list) return 1;
+ /*
+ * If there is no access list allow everything.
+ */
+ if (!access_list)
+ return 1;
for (i = 0; i != vector_length(access_list); ++i) {
acl = vector_getentry(access_list, i, NULL);
switch (acl->type) {
- case ACL_STRING:
- perm = acl_string_processing(acl, ip, host);
- break;
-
- case ACL_NUMERIC:
- if (ip[0] == '\0') continue;
- perm = check_numeric_acl(acl, ip);
- break;
- }
+ case ACL_STRING:
+ perm = acl_string_processing(acl, ip, host);
+ break;
+
+ case ACL_NUMERIC:
+ if (ip[0] == '\0')
+ continue;
+ perm = check_numeric_acl(acl, ip);
+ break;
+ }
/*
* Check the return value too see if the IP address is
- * allowed or denied.
- */
- if (perm == 0)
- break;
- else if (perm == 1)
- return perm;
+ * allowed or denied.
+ */
+ if (perm == 0)
+ break;
+ else if (perm == 1)
+ return perm;
}
- /*
- * Deny all connections by default.
- */
- log_message(LOG_NOTICE, "Unauthorized connection from \"%s\" [%s].",
- host, ip);
- return 0;
+ /*
+ * Deny all connections by default.
+ */
+ log_message(LOG_NOTICE, "Unauthorized connection from \"%s\" [%s].",
+ host, ip);
+ return 0;
}
diff --git a/src/acl.h b/src/acl.h
index 14f492b..3d693d4 100644
--- a/src/acl.h
+++ b/src/acl.h
@@ -1,4 +1,4 @@
-/* $Id: acl.h,v 1.4 2005-07-12 17:39:43 rjkaes Exp $
+/* $Id: acl.h,v 1.5 2005-08-15 03:54:31 rjkaes Exp $
*
* See 'acl.c' for detailed information.
*
@@ -21,6 +21,7 @@
typedef enum { ACL_ALLOW, ACL_DENY } acl_access_t;
extern int insert_acl(char *location, acl_access_t access_type);
-extern int check_acl(int fd, const char* ip_address, const char* string_address);
+extern int check_acl(int fd, const char *ip_address,
+ const char *string_address);
#endif
diff --git a/src/anonymous.c b/src/anonymous.c
index 82ae41e..3c40a3a 100644
--- a/src/anonymous.c
+++ b/src/anonymous.c
@@ -1,4 +1,4 @@
-/* $Id: anonymous.c,v 1.15 2005-07-12 17:39:43 rjkaes Exp $
+/* $Id: anonymous.c,v 1.16 2005-08-15 03:54:31 rjkaes Exp $
*
* Handles insertion and searches for headers which should be let through when
* the anonymous feature is turned on.
@@ -28,7 +28,7 @@ static hashmap_t anonymous_map = NULL;
short int
is_anonymous_enabled(void)
{
- return (anonymous_map != NULL) ? 1 : 0;
+ return (anonymous_map != NULL) ? 1 : 0;
}
/*
@@ -38,10 +38,10 @@ is_anonymous_enabled(void)
int
anonymous_search(char *s)
{
- assert(s != NULL);
- assert(anonymous_map != NULL);
+ assert(s != NULL);
+ assert(anonymous_map != NULL);
- return hashmap_search(anonymous_map, s);
+ return hashmap_search(anonymous_map, s);
}
/*
@@ -53,21 +53,21 @@ anonymous_search(char *s)
int
anonymous_insert(char *s)
{
- char data = 1;
+ char data = 1;
- assert(s != NULL);
+ assert(s != NULL);
- if (!anonymous_map) {
- anonymous_map = hashmap_create(32);
- if (!anonymous_map)
- return -1;
- }
+ if (!anonymous_map) {
+ anonymous_map = hashmap_create(32);
+ if (!anonymous_map)
+ return -1;
+ }
- if (hashmap_search(anonymous_map, s) > 0) {
- /* The key was already found, so return a positive number. */
- return 0;
- }
+ if (hashmap_search(anonymous_map, s) > 0) {
+ /* The key was already found, so return a positive number. */
+ return 0;
+ }
- /* Insert the new key */
- return hashmap_insert(anonymous_map, s, &data, sizeof(data));
+ /* Insert the new key */
+ return hashmap_insert(anonymous_map, s, &data, sizeof(data));
}
diff --git a/src/buffer.c b/src/buffer.c
index 0497fbc..a29cfbc 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1,4 +1,4 @@
-/* $Id: buffer.c,v 1.24 2004-02-13 21:27:42 rjkaes Exp $
+/* $Id: buffer.c,v 1.25 2005-08-15 03:54:31 rjkaes Exp $
*
* 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,
@@ -31,10 +31,10 @@
#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 */
+ 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 */
};
/*
@@ -42,9 +42,9 @@ struct bufline_s {
* (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 bufline_s *head; /* top of the buffer */
+ struct bufline_s *tail; /* bottom of the buffer */
+ size_t size; /* total size of the buffer */
};
/*
@@ -55,28 +55,28 @@ struct buffer_s {
static struct bufline_s *
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;
}
/*
@@ -85,15 +85,15 @@ makenewline(unsigned char *data, size_t length)
static void
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);
}
/*
@@ -102,20 +102,20 @@ free_line(struct bufline_s *line)
struct buffer_s *
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;
}
/*
@@ -124,25 +124,26 @@ new_buffer(void)
void
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)
+size_t
+buffer_size(struct buffer_s *buffptr)
{
- return buffptr->size;
+ return buffptr->size;
}
/*
@@ -151,37 +152,37 @@ size_t buffer_size(struct buffer_s *buffptr)
int
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;
}
/*
@@ -190,17 +191,17 @@ add_to_buffer(struct buffer_s *buffptr, unsigned char *data, size_t length)
static struct bufline_s *
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;
}
/*
@@ -211,51 +212,51 @@ remove_from_buffer(struct buffer_s *buffptr)
ssize_t
read_buffer(int fd, struct buffer_s * buffptr)
{
- ssize_t bytesin;
- unsigned char buffer[READ_BUFFER_SIZE];
-
- assert(fd >= 0);
- assert(buffptr != NULL);
-
- /*
- * Don't allow the buffer to grow larger than MAXBUFFSIZE
- */
- if (buffptr->size >= MAXBUFFSIZE)
- return 0;
-
- 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.");
- return -1;
- }
-
- return bytesin;
- } else {
- if (bytesin == 0) {
- /* connection was closed by client */
- return -1;
- } else {
- switch (errno) {
+ ssize_t bytesin;
+ unsigned char buffer[READ_BUFFER_SIZE];
+
+ assert(fd >= 0);
+ assert(buffptr != NULL);
+
+ /*
+ * Don't allow the buffer to grow larger than MAXBUFFSIZE
+ */
+ if (buffptr->size >= MAXBUFFSIZE)
+ return 0;
+
+ 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.");
+ return -1;
+ }
+
+ return bytesin;
+ } else {
+ if (bytesin == 0) {
+ /* connection was closed by client */
+ return -1;
+ } else {
+ switch (errno) {
#ifdef EWOULDBLOCK
- case EWOULDBLOCK:
+ case EWOULDBLOCK:
#else
# ifdef EAGAIN
- case EAGAIN:
+ case EAGAIN:
# endif
#endif
- case EINTR:
- return 0;
- default:
- log_message(LOG_ERR,
- "readbuff: recv() error \"%s\" on file descriptor %d",
- strerror(errno), fd);
- return -1;
- }
- }
- }
+ case EINTR:
+ return 0;
+ default:
+ log_message(LOG_ERR,
+ "readbuff: recv() error \"%s\" on file descriptor %d",
+ strerror(errno), fd);
+ return -1;
+ }
+ }
+ }
}
/*
@@ -265,50 +266,51 @@ read_buffer(int fd, struct buffer_s * buffptr)
ssize_t
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;
+ }
+ }
}
diff --git a/src/buffer.h b/src/buffer.h
index bb43d72..706743e 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -1,4 +1,4 @@
-/* $Id: buffer.h,v 1.9 2005-07-12 17:39:43 rjkaes Exp $
+/* $Id: buffer.h,v 1.10 2005-08-15 03:54:31 rjkaes Exp $
*
* See 'buffer.c' for a detailed description.
*
@@ -29,9 +29,9 @@ extern size_t buffer_size(struct buffer_s *buffptr);
* Add a new line to the given buffer. The data IS copied into the structure.
*/
extern int add_to_buffer(struct buffer_s *buffptr, unsigned char *data,
- size_t length);
+ size_t length);
extern ssize_t read_buffer(int fd, struct buffer_s *buffptr);
extern ssize_t write_buffer(int fd, struct buffer_s *buffptr);
-#endif /* __BUFFER_H_ */
+#endif /* __BUFFER_H_ */
diff --git a/src/child.c b/src/child.c
index c4a19b2..eb29a78 100644
--- a/src/child.c
+++ b/src/child.c
@@ -1,4 +1,4 @@
-/* $Id: child.c,v 1.17 2005-07-12 17:39:43 rjkaes Exp $
+/* $Id: child.c,v 1.18 2005-08-15 03:54:31 rjkaes Exp $
*
* Handles the creation/destruction of the various children required for
* processing incoming connections.
@@ -35,9 +35,9 @@ static socklen_t addrlen;
*/
enum child_status_t { T_EMPTY, T_WAITING, T_CONNECTED };
struct child_s {
- pid_t tid;
- unsigned int connects;
- enum child_status_t status;
+ pid_t tid;
+ unsigned int connects;
+ enum child_status_t status;
};
/*
@@ -47,11 +47,11 @@ struct child_s {
static struct child_s *child_ptr;
static struct child_config_s {
- int maxclients, maxrequestsperchild;
- int maxspareservers, minspareservers, startservers;
+ int maxclients, maxrequestsperchild;
+ int maxspareservers, minspareservers, startservers;
} child_config;
-static unsigned int* servers_waiting; /* servers waiting for a connection */
+static unsigned int *servers_waiting; /* servers waiting for a connection */
/*
* Lock/Unlock the "servers_waiting" variable so that two children cannot
@@ -72,40 +72,40 @@ static int lock_fd = -1;
static void
_child_lock_init(void)
{
- char lock_file[] = "/tmp/tinyproxy.servers.lock.XXXXXX";
+ char lock_file[] = "/tmp/tinyproxy.servers.lock.XXXXXX";
- lock_fd = mkstemp(lock_file);
- unlink(lock_file);
+ lock_fd = mkstemp(lock_file);
+ unlink(lock_file);
- lock_it.l_type = F_WRLCK;
- lock_it.l_whence = SEEK_SET;
- lock_it.l_start = 0;
- lock_it.l_len = 0;
+ lock_it.l_type = F_WRLCK;
+ lock_it.l_whence = SEEK_SET;
+ lock_it.l_start = 0;
+ lock_it.l_len = 0;
- unlock_it.l_type = F_UNLCK;
- unlock_it.l_whence = SEEK_SET;
- unlock_it.l_start = 0;
- unlock_it.l_len = 0;
+ unlock_it.l_type = F_UNLCK;
+ unlock_it.l_whence = SEEK_SET;
+ unlock_it.l_start = 0;
+ unlock_it.l_len = 0;
}
static void
_child_lock_wait(void)
{
- int rc;
-
- while ((rc = fcntl(lock_fd, F_SETLKW, &lock_it)) < 0) {
- if (errno == EINTR)
- continue;
- else
- return;
- }
+ int rc;
+
+ while ((rc = fcntl(lock_fd, F_SETLKW, &lock_it)) < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ return;
+ }
}
static void
_child_lock_release(void)
{
- if (fcntl(lock_fd, F_SETLKW, &unlock_it) < 0)
- return;
+ if (fcntl(lock_fd, F_SETLKW, &unlock_it) < 0)
+ return;
}
/* END OF LOCKING SECTION */
@@ -131,119 +131,124 @@ _child_lock_release(void)
short int
child_configure(child_config_t type, int val)
{
- switch (type) {
- case CHILD_MAXCLIENTS:
- child_config.maxclients = val;
- break;
- case CHILD_MAXSPARESERVERS:
- child_config.maxspareservers = val;
- break;
- case CHILD_MINSPARESERVERS:
- child_config.minspareservers = val;
- break;
- case CHILD_STARTSERVERS:
- child_config.startservers = val;
- break;
- case CHILD_MAXREQUESTSPERCHILD:
- child_config.maxrequestsperchild = val;
- break;
- default:
- DEBUG2("Invalid type (%d)", type);
- return -1;
- }
-
- return 0;
+ switch (type) {
+ case CHILD_MAXCLIENTS:
+ child_config.maxclients = val;
+ break;
+ case CHILD_MAXSPARESERVERS:
+ child_config.maxspareservers = val;
+ break;
+ case CHILD_MINSPARESERVERS:
+ child_config.minspareservers = val;
+ break;
+ case CHILD_STARTSERVERS:
+ child_config.startservers = val;
+ break;
+ case CHILD_MAXREQUESTSPERCHILD:
+ child_config.maxrequestsperchild = val;
+ break;
+ default:
+ DEBUG2("Invalid type (%d)", type);
+ return -1;
+ }
+
+ return 0;
}
/*
* This is the main (per child) loop.
*/
static void
-child_main(struct child_s* ptr)
+child_main(struct child_s *ptr)
{
- int connfd;
- struct sockaddr *cliaddr;
- socklen_t clilen;
+ int connfd;
+ struct sockaddr *cliaddr;
+ socklen_t clilen;
- cliaddr = safemalloc(addrlen);
- if (!cliaddr) {
- log_message(LOG_CRIT,
- "Could not allocate memory for child address.");
- exit(0);
- }
+ cliaddr = safemalloc(addrlen);
+ if (!cliaddr) {
+ log_message(LOG_CRIT,
+ "Could not allocate memory for child address.");
+ exit(0);
+ }
- ptr->connects = 0;
+ ptr->connects = 0;
- while (!config.quit) {
- ptr->status = T_WAITING;
+ while (!config.quit) {
+ ptr->status = T_WAITING;
- clilen = addrlen;
+ clilen = addrlen;
- connfd = accept(listenfd, cliaddr, &clilen);
+ connfd = accept(listenfd, cliaddr, &clilen);
#ifndef NDEBUG
- /*
- * Enable the TINYPROXY_DEBUG environment variable if you
- * want to use the GDB debugger.
- */
- if (getenv("TINYPROXY_DEBUG")) {
- /* Pause for 10 seconds to allow us to connect debugger */
- fprintf(stderr,
- "Process has accepted connection: %ld\n", (long int)ptr->tid);
- sleep(10);
- fprintf(stderr, "Continuing process: %ld\n", (long int)ptr->tid);
- }
+ /*
+ * Enable the TINYPROXY_DEBUG environment variable if you
+ * want to use the GDB debugger.
+ */
+ if (getenv("TINYPROXY_DEBUG")) {
+ /* Pause for 10 seconds to allow us to connect debugger */
+ fprintf(stderr,
+ "Process has accepted connection: %ld\n",
+ (long int)ptr->tid);
+ sleep(10);
+ fprintf(stderr, "Continuing process: %ld\n",
+ (long int)ptr->tid);
+ }
#endif
- /*
- * Make sure no error occurred...
- */
- if (connfd < 0) {
- log_message(LOG_ERR, "Accept returned an error (%s) ... retrying.", strerror(errno));
- continue;
- }
-
- ptr->status = T_CONNECTED;
-
- SERVER_DEC();
-
- handle_connection(connfd);
- ptr->connects++;
-
- if (child_config.maxrequestsperchild != 0) {
- DEBUG2("%u connections so far...", ptr->connects);
-
- if (ptr->connects == child_config.maxrequestsperchild) {
- log_message(LOG_NOTICE,
- "Child has reached MaxRequestsPerChild (%u). Killing child.",
- ptr->connects);
- break;
- }
- }
-
- SERVER_COUNT_LOCK();
- if (*servers_waiting > child_config.maxspareservers) {
- /*
- * There are too many spare children, kill ourself
- * off.
- */
- log_message(LOG_NOTICE,
- "Waiting servers (%d) exceeds MaxSpareServers (%d). Killing child.",
- *servers_waiting, child_config.maxspareservers);
- SERVER_COUNT_UNLOCK();
-
- break;
- } else {
- SERVER_COUNT_UNLOCK();
- }
-
- SERVER_INC();
- }
-
- ptr->status = T_EMPTY;
-
- safefree(cliaddr);
- exit(0);
+ /*
+ * Make sure no error occurred...
+ */
+ if (connfd < 0) {
+ log_message(LOG_ERR,
+ "Accept returned an error (%s) ... retrying.",
+ strerror(errno));
+ continue;
+ }
+
+ ptr->status = T_CONNECTED;
+
+ SERVER_DEC();
+
+ handle_connection(connfd);
+ ptr->connects++;
+
+ if (child_config.maxrequestsperchild != 0) {
+ DEBUG2("%u connections so far...", ptr->connects);
+
+ if (ptr->connects == child_config.maxrequestsperchild) {
+ log_message(LOG_NOTICE,
+ "Child has reached MaxRequestsPerChild (%u). Killing child.",
+ ptr->connects);
+ break;
+ }
+ }
+
+ SERVER_COUNT_LOCK();
+ if (*servers_waiting > child_config.maxspareservers) {
+ /*
+ * There are too many spare children, kill ourself
+ * off.
+ */
+ log_message(LOG_NOTICE,
+ "Waiting servers (%d) exceeds MaxSpareServers (%d). Killing child.",
+ *servers_waiting,
+ child_config.maxspareservers);
+ SERVER_COUNT_UNLOCK();
+
+ break;
+ } else {
+ SERVER_COUNT_UNLOCK();
+ }
+
+ SERVER_INC();
+ }
+
+ ptr->status = T_EMPTY;
+
+ safefree(cliaddr);
+ exit(0);
}
/*
@@ -251,22 +256,22 @@ child_main(struct child_s* ptr)
* child_main() function.
*/
static pid_t
-child_make(struct child_s* ptr)
+child_make(struct child_s *ptr)
{
- pid_t pid;
-
- if ((pid = fork()) > 0)
- return pid; /* parent */
-
- /*
- * Reset the SIGNALS so that the child can be reaped.
- */
- set_signal_handler(SIGCHLD, SIG_DFL);
- set_signal_handler(SIGTERM, SIG_DFL);
- set_signal_handler(SIGHUP, SIG_DFL);
-
- child_main(ptr); /* never returns */
- return -1;
+ pid_t pid;
+
+ if ((pid = fork()) > 0)
+ return pid; /* parent */
+
+ /*
+ * Reset the SIGNALS so that the child can be reaped.
+ */
+ set_signal_handler(SIGCHLD, SIG_DFL);
+ set_signal_handler(SIGTERM, SIG_DFL);
+ set_signal_handler(SIGHUP, SIG_DFL);
+
+ child_main(ptr); /* never returns */
+ return -1;
}
/*
@@ -275,78 +280,80 @@ child_make(struct child_s* ptr)
short int
child_pool_create(void)
{
- unsigned int i;
-
- /*
- * Make sure the number of MaxClients is not zero, since this
- * variable determines the size of the array created for children
- * later on.
- */
- if (child_config.maxclients == 0) {
- log_message(LOG_ERR,
- "child_pool_create: \"MaxClients\" must be greater than zero.");
- return -1;
- }
- if (child_config.startservers == 0) {
- log_message(LOG_ERR,
- "child_pool_create: \"StartServers\" must be greater than zero.");
- return -1;
- }
-
- child_ptr = calloc_shared_memory(child_config.maxclients,
- sizeof(struct child_s));
- if (!child_ptr) {
- log_message(LOG_ERR, "Could not allocate memory for children.");
- return -1;
- }
-
- servers_waiting = malloc_shared_memory(sizeof(unsigned int));
- if (servers_waiting == MAP_FAILED) {
- log_message(LOG_ERR, "Could not allocate memory for child counting.");
- return -1;
- }
- *servers_waiting = 0;
-
- /*
- * Create a "locking" file for use around the servers_waiting
- * variable.
- */
- _child_lock_init();
-
- if (child_config.startservers > child_config.maxclients) {
- log_message(LOG_WARNING,
- "Can not start more than \"MaxClients\" servers. Starting %u servers instead.",
- child_config.maxclients);
- child_config.startservers = child_config.maxclients;
- }
-
- for (i = 0; i != child_config.maxclients; i++) {
- child_ptr[i].status = T_EMPTY;
- child_ptr[i].connects = 0;
- }
-
- for (i = 0; i != child_config.startservers; i++) {
- DEBUG2("Trying to create child %d of %d", i + 1, child_config.startservers);
- child_ptr[i].status = T_WAITING;
- child_ptr[i].tid = child_make(&child_ptr[i]);
-
- if (child_ptr[i].tid < 0) {
- log_message(LOG_WARNING,
- "Could not create child number %d of %d",
- i, child_config.startservers);
- return -1;
- } else {
- log_message(LOG_INFO,
- "Creating child number %d of %d ...",
- i + 1, child_config.startservers);
-
- SERVER_INC();
- }
- }
-
- log_message(LOG_INFO, "Finished creating all children.");
-
- return 0;
+ unsigned int i;
+
+ /*
+ * Make sure the number of MaxClients is not zero, since this
+ * variable determines the size of the array created for children
+ * later on.
+ */
+ if (child_config.maxclients == 0) {
+ log_message(LOG_ERR,
+ "child_pool_create: \"MaxClients\" must be greater than zero.");
+ return -1;
+ }
+ if (child_config.startservers == 0) {
+ log_message(LOG_ERR,
+ "child_pool_create: \"StartServers\" must be greater than zero.");
+ return -1;
+ }
+
+ child_ptr = calloc_shared_memory(child_config.maxclients,
+ sizeof(struct child_s));
+ if (!child_ptr) {
+ log_message(LOG_ERR, "Could not allocate memory for children.");
+ return -1;
+ }
+
+ servers_waiting = malloc_shared_memory(sizeof(unsigned int));
+ if (servers_waiting == MAP_FAILED) {
+ log_message(LOG_ERR,
+ "Could not allocate memory for child counting.");
+ return -1;
+ }
+ *servers_waiting = 0;
+
+ /*
+ * Create a "locking" file for use around the servers_waiting
+ * variable.
+ */
+ _child_lock_init();
+
+ if (child_config.startservers > child_config.maxclients) {
+ log_message(LOG_WARNING,
+ "Can not start more than \"MaxClients\" servers. Starting %u servers instead.",
+ child_config.maxclients);
+ child_config.startservers = child_config.maxclients;
+ }
+
+ for (i = 0; i != child_config.maxclients; i++) {
+ child_ptr[i].status = T_EMPTY;
+ child_ptr[i].connects = 0;
+ }
+
+ for (i = 0; i != child_config.startservers; i++) {
+ DEBUG2("Trying to create child %d of %d", i + 1,
+ child_config.startservers);
+ child_ptr[i].status = T_WAITING;
+ child_ptr[i].tid = child_make(&child_ptr[i]);
+
+ if (child_ptr[i].tid < 0) {
+ log_message(LOG_WARNING,
+ "Could not create child number %d of %d",
+ i, child_config.startservers);
+ return -1;
+ } else {
+ log_message(LOG_INFO,
+ "Creating child number %d of %d ...",
+ i + 1, child_config.startservers);
+
+ SERVER_INC();
+ }
+ }
+
+ log_message(LOG_INFO, "Finished creating all children.");
+
+ return 0;
}
/*
@@ -356,59 +363,61 @@ child_pool_create(void)
void
child_main_loop(void)
{
- unsigned int i;
-
- while (1) {
- if (config.quit)
- return;
-
- /* If there are not enough spare servers, create more */
- SERVER_COUNT_LOCK();
- if (*servers_waiting < child_config.minspareservers) {
- log_message(LOG_NOTICE,
- "Waiting servers (%d) is less than MinSpareServers (%d). Creating new child.",
- *servers_waiting, child_config.minspareservers);
-
- SERVER_COUNT_UNLOCK();
-
- for (i = 0; i != child_config.maxclients; i++) {
- if (child_ptr[i].status == T_EMPTY) {
- child_ptr[i].status = T_WAITING;
- child_ptr[i].tid = child_make(&child_ptr[i]);
- if (child_ptr[i].tid < 0) {
- log_message(LOG_NOTICE,
- "Could not create child");
-
- child_ptr[i].status = T_EMPTY;
- break;
- }
-
- SERVER_INC();
-
- break;
- }
- }
- } else {
- SERVER_COUNT_UNLOCK();
- }
-
- sleep(5);
-
- /* Handle log rotation if it was requested */
- if (received_sighup) {
- truncate_log_file();
+ unsigned int i;
+
+ while (1) {
+ if (config.quit)
+ return;
+
+ /* If there are not enough spare servers, create more */
+ SERVER_COUNT_LOCK();
+ if (*servers_waiting < child_config.minspareservers) {
+ log_message(LOG_NOTICE,
+ "Waiting servers (%d) is less than MinSpareServers (%d). Creating new child.",
+ *servers_waiting,
+ child_config.minspareservers);
+
+ SERVER_COUNT_UNLOCK();
+
+ for (i = 0; i != child_config.maxclients; i++) {
+ if (child_ptr[i].status == T_EMPTY) {
+ child_ptr[i].status = T_WAITING;
+ child_ptr[i].tid =
+ child_make(&child_ptr[i]);
+ if (child_ptr[i].tid < 0) {
+ log_message(LOG_NOTICE,
+ "Could not create child");
+
+ child_ptr[i].status = T_EMPTY;
+ break;
+ }
+
+ SERVER_INC();
+
+ break;
+ }
+ }
+ } else {
+ SERVER_COUNT_UNLOCK();
+ }
+
+ sleep(5);
+
+ /* Handle log rotation if it was requested */
+ if (received_sighup) {
+ truncate_log_file();
#ifdef FILTER_ENABLE
- if (config.filter) {
- filter_destroy();
- filter_init();
- }
- log_message(LOG_NOTICE, "Re-reading filter file.");
-#endif /* FILTER_ENABLE */
-
- received_sighup = FALSE;
- }
- }
+ if (config.filter) {
+ filter_destroy();
+ filter_init();
+ }
+ log_message(LOG_NOTICE, "Re-reading filter file.");
+#endif /* FILTER_ENABLE */
+
+ received_sighup = FALSE;
+ }
+ }
}
/*
@@ -417,23 +426,23 @@ child_main_loop(void)
void
child_kill_children(void)
{
- unsigned int i;
-
- for (i = 0; i != child_config.maxclients; i++) {
- if (child_ptr[i].status != T_EMPTY)
- kill(child_ptr[i].tid, SIGTERM);
- }
+ unsigned int i;
+
+ for (i = 0; i != child_config.maxclients; i++) {
+ if (child_ptr[i].status != T_EMPTY)
+ kill(child_ptr[i].tid, SIGTERM);
+ }
}
int
child_listening_sock(uint16_t port)
{
- listenfd = listen_sock(port, &addrlen);
- return listenfd;
+ listenfd = listen_sock(port, &addrlen);
+ return listenfd;
}
void
child_close_sock(void)
{
- close(listenfd);
+ close(listenfd);
}
diff --git a/src/child.h b/src/child.h
index d2f195f..41210f3 100644
--- a/src/child.h
+++ b/src/child.h
@@ -1,4 +1,4 @@
-/* $Id: child.h,v 1.3 2005-07-12 17:39:43 rjkaes Exp $
+/* $Id: child.h,v 1.4 2005-08-15 03:54:31 rjkaes Exp $
*
* See 'child.c' for more information.
*
@@ -19,11 +19,11 @@
#define TINYPROXY_CHILD_H
typedef enum {
- CHILD_MAXCLIENTS,
- CHILD_MAXSPARESERVERS,
- CHILD_MINSPARESERVERS,
- CHILD_STARTSERVERS,
- CHILD_MAXREQUESTSPERCHILD
+ CHILD_MAXCLIENTS,
+ CHILD_MAXSPARESERVERS,
+ CHILD_MINSPARESERVERS,
+ CHILD_STARTSERVERS,
+ CHILD_MAXREQUESTSPERCHILD
} child_config_t;
extern short int child_pool_create(void);
diff --git a/src/common.h b/src/common.h
index b1cd452..5100bcc 100644
--- a/src/common.h
+++ b/src/common.h
@@ -1,4 +1,4 @@
-/* $Id: common.h,v 1.8 2005-07-12 17:39:43 rjkaes Exp $
+/* $Id: common.h,v 1.9 2005-08-15 03:54:31 rjkaes Exp $
*
* This file groups all the headers required throughout the tinyproxy
* system. All this information use to be in the "tinyproxy.h" header,
@@ -166,13 +166,13 @@
# define MSG_NOSIGNAL (0)
#endif
-#ifndef SHUT_RD /* these three Posix.1g names are quite new */
-# define SHUT_RD 0 /* shutdown for reading */
-# define SHUT_WR 1 /* shutdown for writing */
-# define SHUT_RDWR 2 /* shutdown for reading and writing */
+#ifndef SHUT_RD /* these three Posix.1g names are quite new */
+# define SHUT_RD 0 /* shutdown for reading */
+# define SHUT_WR 1 /* shutdown for writing */
+# define SHUT_RDWR 2 /* shutdown for reading and writing */
#endif
-#define MAXLISTEN 1024 /* Max number of connections */
+#define MAXLISTEN 1024 /* Max number of connections */
/*
* SunOS doesn't have INADDR_NONE defined.
diff --git a/src/conffile.c b/src/conffile.c
index 54c5c50..453942f 100644
--- a/src/conffile.c
+++ b/src/conffile.c
@@ -1,4 +1,4 @@
-/* $Id: conffile.c,v 1.4 2004-08-24 16:34:22 rjkaes Exp $
+/* $Id: conffile.c,v 1.5 2005-08-15 03:54:31 rjkaes Exp $
*
* Parses the configuration file and sets up the config_s structure for
* use by the application. This file replaces the old grammar.y and
@@ -57,12 +57,11 @@
*/
#define RE_MAX_MATCHES 16
-
/*
* All configuration handling functions are REQUIRED to be defined
* with the same function template as below.
*/
-typedef int (*CONFFILE_HANDLER)(struct config_s*, const char*, regmatch_t[]);
+typedef int (*CONFFILE_HANDLER) (struct config_s *, const char *, regmatch_t[]);
/*
* Define the pattern used by any directive handling function. The
@@ -77,12 +76,16 @@ typedef int (*CONFFILE_HANDLER)(struct config_s*, const char*, regmatch_t[]);
*/
#define HANDLE_FUNC(func) int func(struct config_s* conf, const char* line, regmatch_t match[])
-
/*
* List all the handling functions. These are defined later, but they need
* to be in-scope before the big structure below.
*/
-static HANDLE_FUNC(handle_nop) { return 0; } /* do nothing function */
+static
+HANDLE_FUNC(handle_nop)
+{
+ return 0;
+} /* do nothing function */
+
static HANDLE_FUNC(handle_allow);
static HANDLE_FUNC(handle_anonymous);
static HANDLE_FUNC(handle_bind);
@@ -115,12 +118,12 @@ static HANDLE_FUNC(handle_statfile);
static HANDLE_FUNC(handle_stathost);
static HANDLE_FUNC(handle_syslog);
static HANDLE_FUNC(handle_timeout);
+
//static HANDLE_FUNC(handle_upstream);
static HANDLE_FUNC(handle_user);
static HANDLE_FUNC(handle_viaproxyname);
static HANDLE_FUNC(handle_xtinyproxy);
-
/*
* This macro can be used to make standard directives in the form:
* directive arguments [arguments ...]
@@ -134,7 +137,6 @@ static HANDLE_FUNC(handle_xtinyproxy);
*/
#define STDCONF(d, re, func) { BEGIN "(" d ")" WS re END, func, NULL }
-
/*
* Holds the regular expression used to match the configuration directive,
* the function pointer to the routine to handle the directive, and
@@ -142,74 +144,66 @@ static HANDLE_FUNC(handle_xtinyproxy);
* to be compiled one.
*/
struct {
- const char* re;
+ const char *re;
CONFFILE_HANDLER handler;
- regex_t* cre;
+ regex_t *cre;
} directives[] = {
/* comments */
- { BEGIN "#", handle_nop },
-
- /* blank lines */
- { "^[[:space:]]+$", handle_nop },
-
- /* string arguments */
- STDCONF("logfile", STR, handle_logfile),
- STDCONF("pidfile", STR, handle_pidfile),
- STDCONF("anonymous", STR, handle_anonymous),
- STDCONF("viaproxyname", STR, handle_viaproxyname),
- STDCONF("defaulterrorfile", STR, handle_defaulterrorfile),
- STDCONF("statfile", STR, handle_statfile),
- STDCONF("stathost", STR, handle_stathost),
- STDCONF("xtinyproxy", STR, handle_xtinyproxy),
-
- /* boolean arguments */
- STDCONF("syslog", BOOL, handle_syslog),
- STDCONF("bindsame", BOOL, handle_bindsame),
-
- /* integer arguments */
- STDCONF("port", INT, handle_port),
- STDCONF("maxclients", INT, handle_maxclients),
- STDCONF("maxspareservers", INT, handle_maxspareservers),
- STDCONF("minspareservers", INT, handle_minspareservers),
- STDCONF("startservers", INT, handle_startservers),
- STDCONF("maxrequestsperchild", INT, handle_maxrequestsperchild),
- STDCONF("timeout", INT, handle_timeout),
- STDCONF("connectport", INT, handle_connectport),
-
- /* alphanumeric arguments */
- STDCONF("user", ALNUM, handle_user),
- STDCONF("group", ALNUM, handle_group),
-
- /* ip arguments */
- STDCONF("listen", IP, handle_listen),
- STDCONF("allow", "(" IPMASK "|" ALNUM ")", handle_allow),
- STDCONF("deny", "(" IPMASK "|" ALNUM ")", handle_deny),
- STDCONF("bind", IP, handle_bind),
-
- /* error files */
- STDCONF("errorfile", INT WS STR, handle_errorfile),
-
- /* filtering */
- STDCONF("filter", STR, handle_filter),
- STDCONF("filterurls", BOOL, handle_filterurls),
- STDCONF("filterextended", BOOL, handle_filterextended),
- STDCONF("filterdefaultdeny", BOOL, handle_filterdefaultdeny),
- STDCONF("filtercasesensitive", BOOL, handle_filtercasesensitive),
-
- /* Reverse proxy arguments */
- STDCONF("reversebaseurl", STR, handle_reversebaseurl),
- STDCONF("reverseonly", BOOL, handle_reverseonly),
- STDCONF("reversemagic", BOOL, handle_reversemagic),
- STDCONF("reversepath", STR WS "(" STR ")?", handle_reversepath),
-
- /* upstream is rather complicated */
+ {
+ BEGIN "#", handle_nop},
+ /* blank lines */
+ {
+ "^[[:space:]]+$", handle_nop},
+ /* string arguments */
+ STDCONF("logfile", STR, handle_logfile),
+ STDCONF("pidfile", STR, handle_pidfile),
+ STDCONF("anonymous", STR, handle_anonymous),
+ STDCONF("viaproxyname", STR, handle_viaproxyname),
+ STDCONF("defaulterrorfile", STR, handle_defaulterrorfile),
+ STDCONF("statfile", STR, handle_statfile),
+ STDCONF("stathost", STR, handle_stathost),
+ STDCONF("xtinyproxy", STR, handle_xtinyproxy),
+ /* boolean arguments */
+ STDCONF("syslog", BOOL, handle_syslog),
+ STDCONF("bindsame", BOOL, handle_bindsame),
+ /* integer arguments */
+ STDCONF("port", INT, handle_port),
+ STDCONF("maxclients", INT, handle_maxclients),
+ STDCONF("maxspareservers", INT, handle_maxspareservers),
+ STDCONF("minspareservers", INT, handle_minspareservers),
+ STDCONF("startservers", INT, handle_startservers),
+ STDCONF("maxrequestsperchild", INT, handle_maxrequestsperchild),
+ STDCONF("timeout", INT, handle_timeout),
+ STDCONF("connectport", INT, handle_connectport),
+ /* alphanumeric arguments */
+ STDCONF("user", ALNUM, handle_user),
+ STDCONF("group", ALNUM, handle_group),
+ /* ip arguments */
+ STDCONF("listen", IP, handle_listen),
+ STDCONF("allow", "(" IPMASK "|" ALNUM ")", handle_allow),
+ STDCONF("deny", "(" IPMASK "|" ALNUM ")", handle_deny),
+ STDCONF("bind", IP, handle_bind),
+ /* error files */
+ STDCONF("errorfile", INT WS STR, handle_errorfile),
+ /* filtering */
+ STDCONF("filter", STR, handle_filter),
+ STDCONF("filterurls", BOOL, handle_filterurls),
+ STDCONF("filterextended", BOOL, handle_filterextended),
+ STDCONF("filterdefaultdeny", BOOL, handle_filterdefaultdeny),
+ STDCONF("filtercasesensitive", BOOL, handle_filtercasesensitive),
+ /* Reverse proxy arguments */
+ STDCONF("reversebaseurl", STR, handle_reversebaseurl),
+ STDCONF("reverseonly", BOOL, handle_reverseonly),
+ STDCONF("reversemagic", BOOL, handle_reversemagic),
+ STDCONF("reversepath", STR WS "(" STR ")?", handle_reversepath),
+ /* upstream is rather complicated */
// { BEGIN "no" WS "upstream" WS STR END, handle_no_upstream },
// { BEGIN "upstream" WS IP ":" INT "(" WS STR ")" END, handle_upstream },
-
- /* loglevel */
- STDCONF("loglevel", "(critical|error|warning|notice|connect|info)", handle_loglevel)
+ /* loglevel */
+ STDCONF("loglevel", "(critical|error|warning|notice|connect|info)",
+ handle_loglevel)
};
-const unsigned int ndirectives = sizeof(directives)/sizeof(directives[0]);
+const unsigned int ndirectives = sizeof(directives) / sizeof(directives[0]);
/*
* Compiles the regular expressions used by the configuration file. This
@@ -225,7 +219,7 @@ config_compile(void)
for (i = 0; i != ndirectives; ++i) {
assert(directives[i].handler);
assert(!directives[i].cre);
-
+
directives[i].cre = safemalloc(sizeof(regex_t));
if (!directives[i].cre)
return -1;
@@ -233,12 +227,12 @@ config_compile(void)
r = regcomp(directives[i].cre,
directives[i].re,
REG_EXTENDED | REG_ICASE | REG_NEWLINE);
- if (r) return r;
+ if (r)
+ return r;
}
return 0;
}
-
/*
* Attempt to match the supplied line with any of the configuration
* regexes defined above. If a match is found, call the handler
@@ -248,7 +242,7 @@ config_compile(void)
* a negative number is returned.
*/
static int
-check_match(struct config_s* conf, const char* line)
+check_match(struct config_s *conf, const char *line)
{
regmatch_t match[RE_MAX_MATCHES];
unsigned int i;
@@ -258,7 +252,7 @@ check_match(struct config_s* conf, const char* line)
for (i = 0; i != ndirectives; ++i) {
assert(directives[i].cre);
if (!regexec(directives[i].cre, line, RE_MAX_MATCHES, match, 0))
- return (*directives[i].handler)(conf, line, match);
+ return (*directives[i].handler) (conf, line, match);
}
return -1;
@@ -268,9 +262,9 @@ check_match(struct config_s* conf, const char* line)
* Parse the previously opened configuration stream.
*/
int
-config_parse(struct config_s* conf, FILE* f)
+config_parse(struct config_s *conf, FILE * f)
{
- char buffer[1024]; /* 1KB lines should be plenty */
+ char buffer[1024]; /* 1KB lines should be plenty */
unsigned long lineno = 1;
while (fgets(buffer, sizeof(buffer), f)) {
@@ -283,7 +277,6 @@ config_parse(struct config_s* conf, FILE* f)
return 0;
}
-
/***********************************************************************
*
* The following are basic data extraction building blocks that can
@@ -291,15 +284,15 @@ config_parse(struct config_s* conf, FILE* f)
*
***********************************************************************/
-static char*
-get_string_arg(const char* line, regmatch_t* match)
+static char *
+get_string_arg(const char *line, regmatch_t * match)
{
char *p;
const unsigned int len = match->rm_eo - match->rm_so;
assert(line);
assert(len > 0);
-
+
p = safemalloc(len + 1);
if (!p)
return NULL;
@@ -310,9 +303,10 @@ get_string_arg(const char* line, regmatch_t* match)
}
static int
-set_string_arg(char** var, const char* line, regmatch_t* match)
+set_string_arg(char **var, const char *line, regmatch_t * match)
{
- char* arg = get_string_arg(line, match);
+ char *arg = get_string_arg(line, match);
+
if (!arg)
return -1;
*var = safestrdup(arg);
@@ -321,9 +315,9 @@ set_string_arg(char** var, const char* line, regmatch_t* match)
}
static int
-get_bool_arg(const char* line, regmatch_t* match)
+get_bool_arg(const char *line, regmatch_t * match)
{
- const char* p = line + match->rm_so;
+ const char *p = line + match->rm_so;
assert(line);
assert(match && match->rm_so != -1);
@@ -336,36 +330,35 @@ get_bool_arg(const char* line, regmatch_t* match)
}
static int
-set_bool_arg(unsigned int* var, const char* line, regmatch_t* match)
+set_bool_arg(unsigned int *var, const char *line, regmatch_t * match)
{
assert(var);
assert(line);
assert(match && match->rm_so != -1);
-
+
*var = get_bool_arg(line, match);
return 0;
}
static inline long int
-get_int_arg(const char* line, regmatch_t* match)
+get_int_arg(const char *line, regmatch_t * match)
{
assert(line);
assert(match && match->rm_so != -1);
-
+
return strtol(line + match->rm_so, NULL, 0);
}
static int
-set_int_arg(int long* var, const char* line, regmatch_t* match)
+set_int_arg(int long *var, const char *line, regmatch_t * match)
{
assert(var);
assert(line);
assert(match);
-
+
*var = get_int_arg(line, match);
return 0;
}
-
/***********************************************************************
*
* Below are all the directive handling functions. You will notice
@@ -384,17 +377,23 @@ set_int_arg(int long* var, const char* line, regmatch_t* match)
*
***********************************************************************/
-static HANDLE_FUNC(handle_logfile)
+static
+HANDLE_FUNC(handle_logfile)
{
return set_string_arg(&conf->logf_name, line, &match[2]);
}
-static HANDLE_FUNC(handle_pidfile)
+
+static
+HANDLE_FUNC(handle_pidfile)
{
return set_string_arg(&conf->pidpath, line, &match[2]);
}
-static HANDLE_FUNC(handle_anonymous)
+
+static
+HANDLE_FUNC(handle_anonymous)
{
char *arg = get_string_arg(line, &match[2]);
+
if (!arg)
return -1;
@@ -402,35 +401,46 @@ static HANDLE_FUNC(handle_anonymous)
safefree(arg);
return 0;
}
-static HANDLE_FUNC(handle_viaproxyname)
+
+static
+HANDLE_FUNC(handle_viaproxyname)
{
int r = set_string_arg(&conf->via_proxy_name, line, &match[2]);
- if (r) return r;
+
+ if (r)
+ return r;
log_message(LOG_INFO,
- "Setting \"Via\" header proxy to %s",
- conf->via_proxy_name);
+ "Setting \"Via\" header proxy to %s", conf->via_proxy_name);
return 0;
}
-static HANDLE_FUNC(handle_defaulterrorfile)
+
+static
+HANDLE_FUNC(handle_defaulterrorfile)
{
return set_string_arg(&conf->errorpage_undef, line, &match[2]);
}
-static HANDLE_FUNC(handle_statfile)
+
+static
+HANDLE_FUNC(handle_statfile)
{
return set_string_arg(&conf->statpage, line, &match[2]);
}
-static HANDLE_FUNC(handle_stathost)
+
+static
+HANDLE_FUNC(handle_stathost)
{
int r = set_string_arg(&conf->stathost, line, &match[2]);
- if (r) return r;
- log_message(LOG_INFO,
- "Stathost set to \"%s\"",
- conf->stathost);
+
+ if (r)
+ return r;
+ log_message(LOG_INFO, "Stathost set to \"%s\"", conf->stathost);
return 0;
}
-static HANDLE_FUNC(handle_xtinyproxy)
+
+static
+HANDLE_FUNC(handle_xtinyproxy)
{
-#ifdef XTINYPROXY_ENABLE
+#ifdef XTINYPROXY_ENABLE
return set_string_arg(&conf->my_domain, line, &match[2]);
#else
fprintf(stderr,
@@ -438,91 +448,126 @@ static HANDLE_FUNC(handle_xtinyproxy)
return 1;
#endif
}
-static HANDLE_FUNC(handle_syslog)
+
+static
+HANDLE_FUNC(handle_syslog)
{
-#ifdef HAVE_SYSLOG_H
+#ifdef HAVE_SYSLOG_H
return set_bool_arg(&conf->syslog, line, &match[2]);
#else
- fprintf(stderr,
- "Syslog support not compiled in executable.\n");
+ fprintf(stderr, "Syslog support not compiled in executable.\n");
return 1;
#endif
}
-static HANDLE_FUNC(handle_bindsame)
+
+static
+HANDLE_FUNC(handle_bindsame)
{
int r = set_bool_arg(&conf->bindsame, line, &match[2]);
- if (r) return r;
+
+ if (r)
+ return r;
log_message(LOG_INFO, "Binding outgoing connection to incoming IP");
return 0;
}
-static HANDLE_FUNC(handle_port)
+
+static
+HANDLE_FUNC(handle_port)
{
- return set_int_arg((long int*)&conf->port, line, &match[2]);
+ return set_int_arg((long int *)&conf->port, line, &match[2]);
}
-static HANDLE_FUNC(handle_maxclients)
+
+static
+HANDLE_FUNC(handle_maxclients)
{
child_configure(CHILD_MAXCLIENTS, get_int_arg(line, &match[2]));
return 0;
}
-static HANDLE_FUNC(handle_maxspareservers)
+
+static
+HANDLE_FUNC(handle_maxspareservers)
{
child_configure(CHILD_MAXSPARESERVERS, get_int_arg(line, &match[2]));
return 0;
}
-static HANDLE_FUNC(handle_minspareservers)
+
+static
+HANDLE_FUNC(handle_minspareservers)
{
child_configure(CHILD_MINSPARESERVERS, get_int_arg(line, &match[2]));
return 0;
}
-static HANDLE_FUNC(handle_startservers)
+
+static
+HANDLE_FUNC(handle_startservers)
{
child_configure(CHILD_STARTSERVERS, get_int_arg(line, &match[2]));
return 0;
}
-static HANDLE_FUNC(handle_maxrequestsperchild)
+
+static
+HANDLE_FUNC(handle_maxrequestsperchild)
{
- child_configure(CHILD_MAXREQUESTSPERCHILD, get_int_arg(line, &match[2]));
+ child_configure(CHILD_MAXREQUESTSPERCHILD,
+ get_int_arg(line, &match[2]));
return 0;
}
-static HANDLE_FUNC(handle_timeout)
+
+static
+HANDLE_FUNC(handle_timeout)
{
- return set_int_arg((long int*)&conf->idletimeout, line, &match[2]);
+ return set_int_arg((long int *)&conf->idletimeout, line, &match[2]);
}
-static HANDLE_FUNC(handle_connectport)
+
+static
+HANDLE_FUNC(handle_connectport)
{
add_connect_port_allowed(get_int_arg(line, &match[2]));
return 0;
}
-static HANDLE_FUNC(handle_user)
+
+static
+HANDLE_FUNC(handle_user)
{
return set_string_arg(&conf->username, line, &match[2]);
}
-static HANDLE_FUNC(handle_group)
+
+static
+HANDLE_FUNC(handle_group)
{
return set_string_arg(&conf->group, line, &match[2]);
}
-static HANDLE_FUNC(handle_allow)
+
+static
+HANDLE_FUNC(handle_allow)
{
- char* arg = get_string_arg(line, &match[2]);
+ char *arg = get_string_arg(line, &match[2]);
+
insert_acl(arg, ACL_ALLOW);
safefree(arg);
return 0;
}
-static HANDLE_FUNC(handle_deny)
+
+static
+HANDLE_FUNC(handle_deny)
{
char *arg = get_string_arg(line, &match[2]);
+
insert_acl(arg, ACL_DENY);
safefree(arg);
return 0;
}
-static HANDLE_FUNC(handle_bind)
+
+static
+HANDLE_FUNC(handle_bind)
{
#ifndef TRANSPARENT_PROXY
int r = set_string_arg(&conf->bind_address, line, &match[2]);
- if (r) return r;
+
+ if (r)
+ return r;
log_message(LOG_INFO,
- "Outgoing connections bound to IP %s",
- conf->bind_address);
+ "Outgoing connections bound to IP %s", conf->bind_address);
return 0;
#else
fprintf(stderr,
@@ -530,14 +575,20 @@ static HANDLE_FUNC(handle_bind)
return 1;
#endif
}
-static HANDLE_FUNC(handle_listen)
+
+static
+HANDLE_FUNC(handle_listen)
{
int r = set_string_arg(&conf->ipAddr, line, &match[2]);
- if (r) return r;
+
+ if (r)
+ return r;
log_message(LOG_INFO, "Listing on IP %s", conf->ipAddr);
return 0;
}
-static HANDLE_FUNC(handle_errorfile)
+
+static
+HANDLE_FUNC(handle_errorfile)
{
/*
* Because an integer is defined as ((0x)?[[:digit:]]+) _two_
@@ -548,6 +599,7 @@ static HANDLE_FUNC(handle_errorfile)
*/
long int err = get_int_arg(line, &match[2]);
char *page = get_string_arg(line, &match[4]);
+
add_new_errorpage(page, err);
safefree(page);
return 0;
@@ -557,24 +609,27 @@ static HANDLE_FUNC(handle_errorfile)
* Log level's strings.
*/
struct log_levels_s {
- const char* string;
+ const char *string;
int level;
};
static struct log_levels_s log_levels[] = {
- { "critical", LOG_CRIT },
- { "error", LOG_ERR },
- { "warning", LOG_WARNING },
- { "notice", LOG_NOTICE },
- { "connect", LOG_CONN },
- { "info", LOG_INFO }
+ {"critical", LOG_CRIT},
+ {"error", LOG_ERR},
+ {"warning", LOG_WARNING},
+ {"notice", LOG_NOTICE},
+ {"connect", LOG_CONN},
+ {"info", LOG_INFO}
};
-static HANDLE_FUNC(handle_loglevel)
+static
+HANDLE_FUNC(handle_loglevel)
{
- static const unsigned int nlevels = sizeof(log_levels)/sizeof(log_levels[0]);
+ static const unsigned int nlevels =
+ sizeof(log_levels) / sizeof(log_levels[0]);
unsigned int i;
-
+
char *arg = get_string_arg(line, &match[2]);
+
for (i = 0; i != nlevels; ++i) {
if (!strcasecmp(arg, log_levels[i].string)) {
set_log_level(log_levels[i].level);
@@ -584,29 +639,37 @@ static HANDLE_FUNC(handle_loglevel)
return -1;
}
-
#ifdef FILTER_ENABLE
-static HANDLE_FUNC(handle_filter)
+static
+HANDLE_FUNC(handle_filter)
{
return set_string_arg(&conf->filter, line, &match[2]);
}
-static HANDLE_FUNC(handle_filterurls)
+
+static
+HANDLE_FUNC(handle_filterurls)
{
return set_bool_arg(&conf->filter_url, line, &match[2]);
}
-static HANDLE_FUNC(handle_filterextended)
+
+static
+HANDLE_FUNC(handle_filterextended)
{
return set_bool_arg(&conf->filter_extended, line, &match[2]);
}
-static HANDLE_FUNC(handle_filterdefaultdeny)
+
+static
+HANDLE_FUNC(handle_filterdefaultdeny)
{
assert(match[2].rm_so != -1);
-
+
if (get_bool_arg(line, &match[2]))
filter_set_default_policy(FILTER_DEFAULT_DENY);
return 0;
}
-static HANDLE_FUNC(handle_filtercasesensitive)
+
+static
+HANDLE_FUNC(handle_filtercasesensitive)
{
return set_bool_arg(&conf->filter_casesensitive, line, &match[2]);
}
@@ -618,29 +681,59 @@ no_filter_support(void)
return -1;
}
-static HANDLE_FUNC(handle_filter) { return no_filter_support(); }
-static HANDLE_FUNC(handle_filtercasesensitive) { return no_filter_support(); }
-static HANDLE_FUNC(handle_filterdefaultdeny) { return no_filter_support(); }
-static HANDLE_FUNC(handle_filterextended) { return no_filter_support(); }
-static HANDLE_FUNC(handle_filterurls) { return no_filter_support(); }
+static
+HANDLE_FUNC(handle_filter)
+{
+ return no_filter_support();
+}
-#endif
+static
+HANDLE_FUNC(handle_filtercasesensitive)
+{
+ return no_filter_support();
+}
+
+static
+HANDLE_FUNC(handle_filterdefaultdeny)
+{
+ return no_filter_support();
+}
+
+static
+HANDLE_FUNC(handle_filterextended)
+{
+ return no_filter_support();
+}
+
+static
+HANDLE_FUNC(handle_filterurls)
+{
+ return no_filter_support();
+}
+#endif
#ifdef REVERSE_SUPPORT
-static HANDLE_FUNC(handle_reverseonly)
+static
+HANDLE_FUNC(handle_reverseonly)
{
return set_bool_arg(&conf->reverseonly, line, &match[2]);
}
-static HANDLE_FUNC(handle_reversemagic)
+
+static
+HANDLE_FUNC(handle_reversemagic)
{
return set_bool_arg(&conf->reversemagic, line, &match[2]);
}
-static HANDLE_FUNC(handle_reversebaseurl)
+
+static
+HANDLE_FUNC(handle_reversebaseurl)
{
return set_string_arg(&conf->reversebaseurl, line, &match[2]);
}
-static HANDLE_FUNC(handle_reversepath)
+
+static
+HANDLE_FUNC(handle_reversepath)
{
/*
* The second string argument is optional.
@@ -648,7 +741,8 @@ static HANDLE_FUNC(handle_reversepath)
char *arg1, *arg2;
arg1 = get_string_arg(line, &match[2]);
- if (!arg1) return -1;
+ if (!arg1)
+ return -1;
if (match[3].rm_so != -1) {
arg2 = get_string_arg(line, &match[3]);
@@ -674,9 +768,28 @@ no_reverse_support(void)
return -1;
}
-static HANDLE_FUNC(handle_reversebaseurl) { return no_reverse_support(); }
-static HANDLE_FUNC(handle_reversemagic) { return no_reverse_support(); }
-static HANDLE_FUNC(handle_reverseonly) { return no_reverse_support(); }
-static HANDLE_FUNC(handle_reversepath) { return no_reverse_support(); }
+static
+HANDLE_FUNC(handle_reversebaseurl)
+{
+ return no_reverse_support();
+}
+
+static
+HANDLE_FUNC(handle_reversemagic)
+{
+ return no_reverse_support();
+}
+
+static
+HANDLE_FUNC(handle_reverseonly)
+{
+ return no_reverse_support();
+}
+
+static
+HANDLE_FUNC(handle_reversepath)
+{
+ return no_reverse_support();
+}
#endif
diff --git a/src/conffile.h b/src/conffile.h
index 518bf3b..5aef2ca 100644
--- a/src/conffile.h
+++ b/src/conffile.h
@@ -1,4 +1,4 @@
-/* $Id: conffile.h,v 1.1 2004-08-13 20:19:50 rjkaes Exp $
+/* $Id: conffile.h,v 1.2 2005-08-15 03:54:31 rjkaes Exp $
*
* See 'conffile.c' for more details.
*
@@ -19,6 +19,6 @@
#define TINYPROXY_CONFFILE_H
extern int config_compile(void);
-extern int config_parse(struct config_s* conf, FILE* f);
+extern int config_parse(struct config_s *conf, FILE * f);
#endif
diff --git a/src/conns.c b/src/conns.c
index 82cb457..627a00c 100644
--- a/src/conns.c
+++ b/src/conns.c
@@ -1,4 +1,4 @@
-/* $Id: conns.c,v 1.24 2005-07-12 17:39:43 rjkaes Exp $
+/* $Id: conns.c,v 1.25 2005-08-15 03:54:31 rjkaes Exp $
*
* Create and free the connection structure. One day there could be
* other connection related tasks put here, but for now the header
@@ -27,118 +27,118 @@
#include "stats.h"
struct conn_s *
-initialize_conn(int client_fd, const char* ipaddr, const char* string_addr,
- const char* sock_ipaddr)
+initialize_conn(int client_fd, const char *ipaddr, const char *string_addr,
+ const char *sock_ipaddr)
{
- struct conn_s *connptr;
- struct buffer_s *cbuffer, *sbuffer;
+ struct conn_s *connptr;
+ struct buffer_s *cbuffer, *sbuffer;
- assert(client_fd >= 0);
+ assert(client_fd >= 0);
- /*
- * Allocate the memory for all the internal components
- */
- cbuffer = new_buffer();
- sbuffer = new_buffer();
+ /*
+ * Allocate the memory for all the internal components
+ */
+ cbuffer = new_buffer();
+ sbuffer = new_buffer();
- if (!cbuffer || !sbuffer)
- goto error_exit;
+ if (!cbuffer || !sbuffer)
+ goto error_exit;
- /*
- * Allocate the space for the conn_s structure itself.
- */
- connptr = safemalloc(sizeof(struct conn_s));
- if (!connptr)
- goto error_exit;
+ /*
+ * Allocate the space for the conn_s structure itself.
+ */
+ connptr = safemalloc(sizeof(struct conn_s));
+ if (!connptr)
+ goto error_exit;
- connptr->client_fd = client_fd;
- connptr->server_fd = -1;
+ connptr->client_fd = client_fd;
+ connptr->server_fd = -1;
- connptr->cbuffer = cbuffer;
- connptr->sbuffer = sbuffer;
+ connptr->cbuffer = cbuffer;
+ connptr->sbuffer = sbuffer;
- connptr->request_line = NULL;
+ connptr->request_line = NULL;
- /* These store any error strings */
- connptr->error_variables = NULL;
- connptr->error_string = NULL;
- connptr->error_number = -1;
+ /* These store any error strings */
+ connptr->error_variables = NULL;
+ connptr->error_string = NULL;
+ connptr->error_number = -1;
- connptr->connect_method = FALSE;
- connptr->show_stats = FALSE;
+ connptr->connect_method = FALSE;
+ connptr->show_stats = FALSE;
- connptr->protocol.major = connptr->protocol.minor = 0;
+ connptr->protocol.major = connptr->protocol.minor = 0;
- /* There is _no_ content length initially */
- connptr->content_length.server = connptr->content_length.client = -1;
+ /* There is _no_ content length initially */
+ connptr->content_length.server = connptr->content_length.client = -1;
- connptr->server_ip_addr = sock_ipaddr ? safestrdup(sock_ipaddr) : 0;
- connptr->client_ip_addr = safestrdup(ipaddr);
- connptr->client_string_addr = safestrdup(string_addr);
+ connptr->server_ip_addr = sock_ipaddr ? safestrdup(sock_ipaddr) : 0;
+ connptr->client_ip_addr = safestrdup(ipaddr);
+ connptr->client_string_addr = safestrdup(string_addr);
- connptr->upstream_proxy = NULL;
+ connptr->upstream_proxy = NULL;
- update_stats(STAT_OPEN);
+ update_stats(STAT_OPEN);
#ifdef REVERSE_SUPPORT
- connptr->reversepath = NULL;
+ connptr->reversepath = NULL;
#endif
- return connptr;
+ return connptr;
-error_exit:
- /*
- * If we got here, there was a problem allocating memory
- */
- if (cbuffer)
- delete_buffer(cbuffer);
- if (sbuffer)
- delete_buffer(sbuffer);
+ error_exit:
+ /*
+ * If we got here, there was a problem allocating memory
+ */
+ if (cbuffer)
+ delete_buffer(cbuffer);
+ if (sbuffer)
+ delete_buffer(sbuffer);
- return NULL;
+ return NULL;
}
void
destroy_conn(struct conn_s *connptr)
{
- assert(connptr != NULL);
-
- if (connptr->client_fd != -1)
- if (close(connptr->client_fd) < 0)
- log_message(LOG_INFO, "Client (%d) close message: %s",
- connptr->client_fd, strerror(errno));
- if (connptr->server_fd != -1)
- if (close(connptr->server_fd) < 0)
- log_message(LOG_INFO, "Server (%d) close message: %s",
- connptr->server_fd, strerror(errno));
-
- if (connptr->cbuffer)
- delete_buffer(connptr->cbuffer);
- if (connptr->sbuffer)
- delete_buffer(connptr->sbuffer);
-
- if (connptr->request_line)
- safefree(connptr->request_line);
-
- if (connptr->error_variables)
- hashmap_delete(connptr->error_variables);
-
- if (connptr->error_string)
- safefree(connptr->error_string);
-
- if (connptr->server_ip_addr)
- safefree(connptr->server_ip_addr);
- if (connptr->client_ip_addr)
- safefree(connptr->client_ip_addr);
- if (connptr->client_string_addr)
- safefree(connptr->client_string_addr);
+ assert(connptr != NULL);
+
+ if (connptr->client_fd != -1)
+ if (close(connptr->client_fd) < 0)
+ log_message(LOG_INFO, "Client (%d) close message: %s",
+ connptr->client_fd, strerror(errno));
+ if (connptr->server_fd != -1)
+ if (close(connptr->server_fd) < 0)
+ log_message(LOG_INFO, "Server (%d) close message: %s",
+ connptr->server_fd, strerror(errno));
+
+ if (connptr->cbuffer)
+ delete_buffer(connptr->cbuffer);
+ if (connptr->sbuffer)
+ delete_buffer(connptr->sbuffer);
+
+ if (connptr->request_line)
+ safefree(connptr->request_line);
+
+ if (connptr->error_variables)
+ hashmap_delete(connptr->error_variables);
+
+ if (connptr->error_string)
+ safefree(connptr->error_string);
+
+ if (connptr->server_ip_addr)
+ safefree(connptr->server_ip_addr);
+ if (connptr->client_ip_addr)
+ safefree(connptr->client_ip_addr);
+ if (connptr->client_string_addr)
+ safefree(connptr->client_string_addr);
#ifdef REVERSE_SUPPORT
- if (connptr->reversepath)
- safefree(connptr->reversepath);
+ if (connptr->reversepath)
+ safefree(connptr->reversepath);
#endif
- safefree(connptr);
+ safefree(connptr);
- update_stats(STAT_CLOSE);
+ update_stats(STAT_CLOSE);
}
diff --git a/src/conns.h b/src/conns.h
index 0f6a9e1..1c4c9a1 100644
--- a/src/conns.h
+++ b/src/conns.h
@@ -1,4 +1,4 @@
-/* $Id: conns.h,v 1.19 2005-07-12 17:39:43 rjkaes Exp $
+/* $Id: conns.h,v 1.20 2005-08-15 03:54:31 rjkaes Exp $
*
* See 'conns.c' for a detailed description.
*
@@ -25,58 +25,58 @@
* Connection Definition
*/
struct conn_s {
- int client_fd;
- int server_fd;
+ int client_fd;
+ int server_fd;
- struct buffer_s *cbuffer;
- struct buffer_s *sbuffer;
+ struct buffer_s *cbuffer;
+ struct buffer_s *sbuffer;
- /* The request line (first line) from the client */
- char *request_line;
+ /* The request line (first line) from the client */
+ char *request_line;
- /* Booleans */
- unsigned int connect_method;
- unsigned int show_stats;
+ /* Booleans */
+ unsigned int connect_method;
+ unsigned int show_stats;
/*
- * This structure stores key -> value mappings for substitution
- * in the error HTML files.
- */
- hashmap_t error_variables;
-
- int error_number;
- char *error_string;
-
- /* A Content-Length value from the remote server */
- struct {
- long int server;
- long int client;
- } content_length;
-
- /*
- * Store the server's IP (for BindSame)
- */
- char* server_ip_addr;
-
- /*
- * Store the client's IP and hostname information
- */
- char* client_ip_addr;
- char* client_string_addr;
-
- /*
- * Store the incoming request's HTTP protocol.
- */
- struct {
- unsigned int major;
- unsigned int minor;
- } protocol;
+ * This structure stores key -> value mappings for substitution
+ * in the error HTML files.
+ */
+ hashmap_t error_variables;
+
+ int error_number;
+ char *error_string;
+
+ /* A Content-Length value from the remote server */
+ struct {
+ long int server;
+ long int client;
+ } content_length;
+
+ /*
+ * Store the server's IP (for BindSame)
+ */
+ char *server_ip_addr;
+
+ /*
+ * Store the client's IP and hostname information
+ */
+ char *client_ip_addr;
+ char *client_string_addr;
+
+ /*
+ * Store the incoming request's HTTP protocol.
+ */
+ struct {
+ unsigned int major;
+ unsigned int minor;
+ } protocol;
#ifdef REVERSE_SUPPORT
- /*
- * Place to store the current per-connection reverse proxy path
- */
- char* reversepath;
+ /*
+ * Place to store the current per-connection reverse proxy path
+ */
+ char *reversepath;
#endif
/*
@@ -88,9 +88,9 @@ struct conn_s {
/*
* Functions for the creation and destruction of a connection structure.
*/
-extern struct conn_s* initialize_conn(int client_fd, const char* ipaddr,
- const char* string_addr,
- const char* sock_ipaddr);
+extern struct conn_s *initialize_conn(int client_fd, const char *ipaddr,
+ const char *string_addr,
+ const char *sock_ipaddr);
extern void destroy_conn(struct conn_s *connptr);
#endif
diff --git a/src/daemon.c b/src/daemon.c
index f917283..9d4379a 100644
--- a/src/daemon.c
+++ b/src/daemon.c
@@ -1,4 +1,4 @@
-/* $Id: daemon.c,v 1.4 2005-07-12 17:39:43 rjkaes Exp $
+/* $Id: daemon.c,v 1.5 2005-08-15 03:54:31 rjkaes Exp $
*
* This file contains functions which are useful when writing a
* daemon process. The functions include a "makedaemon" function and
@@ -28,26 +28,26 @@
void
makedaemon(void)
{
- if (fork() != 0)
- exit(0);
+ if (fork() != 0)
+ exit(0);
- setsid();
- set_signal_handler(SIGHUP, SIG_IGN);
+ setsid();
+ set_signal_handler(SIGHUP, SIG_IGN);
- if (fork() != 0)
- exit(0);
+ if (fork() != 0)
+ exit(0);
- chdir("/");
- umask(077);
+ chdir("/");
+ umask(077);
#if NDEBUG
/*
* When not in debugging mode, close the standard file
* descriptors.
*/
- close(0);
- close(1);
- close(2);
+ close(0);
+ close(1);
+ close(2);
#endif
}
@@ -56,25 +56,25 @@ makedaemon(void)
* to handle signals sent to the process.
*/
signal_func *
-set_signal_handler(int signo, signal_func *func)
+set_signal_handler(int signo, signal_func * func)
{
- struct sigaction act, oact;
+ struct sigaction act, oact;
- act.sa_handler = func;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0;
- if (signo == SIGALRM) {
+ act.sa_handler = func;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ if (signo == SIGALRM) {
#ifdef SA_INTERRUPT
- act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */
+ act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */
#endif
- } else {
+ } else {
#ifdef SA_RESTART
- act.sa_flags |= SA_RESTART; /* SVR4, 4.4BSD */
+ act.sa_flags |= SA_RESTART; /* SVR4, 4.4BSD */
#endif
- }
+ }
- if (sigaction(signo, &act, &oact) < 0)
- return SIG_ERR;
+ if (sigaction(signo, &act, &oact) < 0)
+ return SIG_ERR;
- return oact.sa_handler;
+ return oact.sa_handler;
}
diff --git a/src/daemon.h b/src/daemon.h
index a7e0944..2b7432e 100644
--- a/src/daemon.h
+++ b/src/daemon.h
@@ -1,4 +1,4 @@
-/* $Id: daemon.h,v 1.2 2005-07-12 17:39:43 rjkaes Exp $
+/* $Id: daemon.h,v 1.3 2005-08-15 03:54:31 rjkaes Exp $
*
* See 'daemon.c' for a detailed description.
*
@@ -23,7 +23,7 @@ typedef void signal_func(int);
/*
* Pass a singal integer and a function to handle the signal.
*/
-extern signal_func *set_signal_handler(int signo, signal_func *func);
+extern signal_func *set_signal_handler(int signo, signal_func * func);
/*
* Make a program a daemon process
diff --git a/src/filter.c b/src/filter.c
index 161cc66..4f25c74 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -1,4 +1,4 @@
-/* $Id: filter.c,v 1.21 2005-07-12 17:39:43 rjkaes Exp $
+/* $Id: filter.c,v 1.22 2005-08-15 03:54:31 rjkaes Exp $
*
* Copyright (c) 1999 George Talusan (gstalusan@uwaterloo.ca)
* Copyright (c) 2002 James E. Flemer (jflemer@acm.jhu.edu)
@@ -30,9 +30,9 @@
static int err;
struct filter_list {
- struct filter_list *next;
- char *pat;
- regex_t *cpat;
+ struct filter_list *next;
+ char *pat;
+ regex_t *cpat;
};
static struct filter_list *fl = NULL;
@@ -45,158 +45,162 @@ static filter_policy_t default_policy = FILTER_DEFAULT_ALLOW;
void
filter_init(void)
{
- FILE *fd;
- struct filter_list *p;
- char buf[FILTER_BUFFER_LEN];
- char *s;
- int cflags;
-
- if (!fl && !already_init) {
- fd = fopen(config.filter, "r");
- if (fd) {
- p = NULL;
-
- cflags = REG_NEWLINE | REG_NOSUB;
- if (config.filter_extended)
- cflags |= REG_EXTENDED;
- if (!config.filter_casesensitive)
- cflags |= REG_ICASE;
-
- while (fgets(buf, FILTER_BUFFER_LEN, fd)) {
- /*
- * Remove any trailing white space and
- * comments.
- */
- s = buf;
- while (*s) {
- if (isspace((unsigned char)*s)) break;
- if (*s == '#') {
- /*
- * If the '#' char is preceeded by
- * an escape, it's not a comment
- * string.
- */
- if (s == buf || *(s - 1) != '\\')
- break;
- }
- ++s;
- }
- *s = '\0';
-
- /* skip leading whitespace */
- s = buf;
- while (*s && isspace((unsigned char)*s))
- s++;
-
- /* skip blank lines and comments */
- if (*s == '\0')
- continue;
-
- if (!p) /* head of list */
- fl = p =
- safecalloc(1,
- sizeof(struct
- filter_list));
- else { /* next entry */
- p->next =
- safecalloc(1,
- sizeof(struct
- filter_list));
- p = p->next;
- }
-
- p->pat = safestrdup(s);
- p->cpat = safemalloc(sizeof(regex_t));
- if ((err = regcomp(p->cpat, p->pat, cflags)) != 0) {
- fprintf(stderr, "Bad regex in %s: %s\n",
- config.filter, p->pat);
- exit(EX_DATAERR);
- }
- }
- if (ferror(fd)) {
- perror("fgets");
- exit(EX_DATAERR);
- }
- fclose(fd);
-
- already_init = 1;
- }
- }
+ FILE *fd;
+ struct filter_list *p;
+ char buf[FILTER_BUFFER_LEN];
+ char *s;
+ int cflags;
+
+ if (!fl && !already_init) {
+ fd = fopen(config.filter, "r");
+ if (fd) {
+ p = NULL;
+
+ cflags = REG_NEWLINE | REG_NOSUB;
+ if (config.filter_extended)
+ cflags |= REG_EXTENDED;
+ if (!config.filter_casesensitive)
+ cflags |= REG_ICASE;
+
+ while (fgets(buf, FILTER_BUFFER_LEN, fd)) {
+ /*
+ * Remove any trailing white space and
+ * comments.
+ */
+ s = buf;
+ while (*s) {
+ if (isspace((unsigned char)*s))
+ break;
+ if (*s == '#') {
+ /*
+ * If the '#' char is preceeded by
+ * an escape, it's not a comment
+ * string.
+ */
+ if (s == buf
+ || *(s - 1) != '\\')
+ break;
+ }
+ ++s;
+ }
+ *s = '\0';
+
+ /* skip leading whitespace */
+ s = buf;
+ while (*s && isspace((unsigned char)*s))
+ s++;
+
+ /* skip blank lines and comments */
+ if (*s == '\0')
+ continue;
+
+ if (!p) /* head of list */
+ fl = p =
+ safecalloc(1,
+ sizeof(struct
+ filter_list));
+ else { /* next entry */
+ p->next =
+ safecalloc(1,
+ sizeof(struct
+ filter_list));
+ p = p->next;
+ }
+
+ p->pat = safestrdup(s);
+ p->cpat = safemalloc(sizeof(regex_t));
+ if ((err =
+ regcomp(p->cpat, p->pat, cflags)) != 0) {
+ fprintf(stderr, "Bad regex in %s: %s\n",
+ config.filter, p->pat);
+ exit(EX_DATAERR);
+ }
+ }
+ if (ferror(fd)) {
+ perror("fgets");
+ exit(EX_DATAERR);
+ }
+ fclose(fd);
+
+ already_init = 1;
+ }
+ }
}
/* unlink the list */
void
filter_destroy(void)
{
- struct filter_list *p, *q;
-
- if (already_init) {
- for (p = q = fl; p; p = q) {
- regfree(p->cpat);
- safefree(p->cpat);
- safefree(p->pat);
- q = p->next;
- safefree(p);
- }
- fl = NULL;
- already_init = 0;
- }
+ struct filter_list *p, *q;
+
+ if (already_init) {
+ for (p = q = fl; p; p = q) {
+ regfree(p->cpat);
+ safefree(p->cpat);
+ safefree(p->pat);
+ q = p->next;
+ safefree(p);
+ }
+ fl = NULL;
+ already_init = 0;
+ }
}
/* Return 0 to allow, non-zero to block */
int
filter_domain(const char *host)
{
- struct filter_list *p;
- int result;
-
- if (!fl || !already_init)
- goto COMMON_EXIT;
-
- for (p = fl; p; p = p->next) {
- result = regexec(p->cpat, host, (size_t) 0, (regmatch_t *) 0, 0);
-
- if (result == 0) {
- if (default_policy == FILTER_DEFAULT_ALLOW)
- return 1;
- else
- return 0;
- }
- }
-
- COMMON_EXIT:
- if (default_policy == FILTER_DEFAULT_ALLOW)
- return 0;
- else
- return 1;
+ struct filter_list *p;
+ int result;
+
+ if (!fl || !already_init)
+ goto COMMON_EXIT;
+
+ for (p = fl; p; p = p->next) {
+ result =
+ regexec(p->cpat, host, (size_t) 0, (regmatch_t *) 0, 0);
+
+ if (result == 0) {
+ if (default_policy == FILTER_DEFAULT_ALLOW)
+ return 1;
+ else
+ return 0;
+ }
+ }
+
+ COMMON_EXIT:
+ if (default_policy == FILTER_DEFAULT_ALLOW)
+ return 0;
+ else
+ return 1;
}
/* returns 0 to allow, non-zero to block */
int
filter_url(const char *url)
{
- struct filter_list *p;
- int result;
-
- if (!fl || !already_init)
- goto COMMON_EXIT;
-
- for (p = fl; p; p = p->next) {
- result = regexec(p->cpat, url, (size_t) 0, (regmatch_t *) 0, 0);
-
- if (result == 0) {
- if (default_policy == FILTER_DEFAULT_ALLOW)
- return 1;
- else
- return 0;
- }
- }
-
- COMMON_EXIT:
- if (default_policy == FILTER_DEFAULT_ALLOW)
- return 0;
- else
- return 1;
+ struct filter_list *p;
+ int result;
+
+ if (!fl || !already_init)
+ goto COMMON_EXIT;
+
+ for (p = fl; p; p = p->next) {
+ result = regexec(p->cpat, url, (size_t) 0, (regmatch_t *) 0, 0);
+
+ if (result == 0) {
+ if (default_policy == FILTER_DEFAULT_ALLOW)
+ return 1;
+ else
+ return 0;
+ }
+ }
+
+ COMMON_EXIT:
+ if (default_policy == FILTER_DEFAULT_ALLOW)
+ return 0;
+ else
+ return 1;
}
/*
@@ -205,5 +209,5 @@ filter_url(const char *url)
void
filter_set_default_policy(filter_policy_t policy)
{
- default_policy = policy;
+ default_policy = policy;
}
diff --git a/src/filter.h b/src/filter.h
index 6785b08..6db806f 100644
--- a/src/filter.h
+++ b/src/filter.h
@@ -1,4 +1,4 @@
-/* $Id: filter.h,v 1.5 2002-06-07 18:36:21 rjkaes Exp $
+/* $Id: filter.h,v 1.6 2005-08-15 03:54:31 rjkaes Exp $
*
* See 'filter.c' for a detailed description.
*
@@ -19,8 +19,8 @@
#define _TINYPROXY_FILTER_H_
typedef enum {
- FILTER_DEFAULT_ALLOW,
- FILTER_DEFAULT_DENY,
+ FILTER_DEFAULT_ALLOW,
+ FILTER_DEFAULT_DENY,
} filter_policy_t;
extern void filter_init(void);
diff --git a/src/hashmap.c b/src/hashmap.c
index 15e5ffe..c060c60 100644
--- a/src/hashmap.c
+++ b/src/hashmap.c
@@ -1,4 +1,4 @@
-/* $Id: hashmap.c,v 1.16 2005-07-12 17:39:43 rjkaes Exp $
+/* $Id: hashmap.c,v 1.17 2005-08-15 03:54:31 rjkaes Exp $
*
* A hashmap implementation. The keys are case-insensitive NULL terminated
* strings, and the data is arbitrary lumps of data. Copies of both the
@@ -38,11 +38,11 @@
* with.
*/
struct hashentry_s {
- char *key;
- void *data;
- size_t len;
+ char *key;
+ void *data;
+ size_t len;
- struct hashentry_s *prev, *next;
+ struct hashentry_s *prev, *next;
};
struct hashbucket_s {
@@ -50,10 +50,10 @@ struct hashbucket_s {
};
struct hashmap_s {
- unsigned int size;
- hashmap_iter end_iterator;
+ unsigned int size;
+ hashmap_iter end_iterator;
- struct hashbucket_s *buckets;
+ struct hashbucket_s *buckets;
};
/*
@@ -68,23 +68,23 @@ struct hashmap_s {
static int
hashfunc(const char *key, unsigned int size)
{
- uint32_t hash;
-
- if (key == NULL)
- return -EINVAL;
- if (size == 0)
- return -ERANGE;
-
- for (hash = tolower(*key++); *key != '\0'; key++) {
- uint32_t bit =
- (hash & 1) ? (1 << (sizeof(uint32_t) - 1)) : 0;
- hash >>= 1;
-
- hash += tolower(*key) + bit;
- }
-
- /* Keep the hash within the table limits */
- return hash % size;
+ uint32_t hash;
+
+ if (key == NULL)
+ return -EINVAL;
+ if (size == 0)
+ return -ERANGE;
+
+ for (hash = tolower(*key++); *key != '\0'; key++) {
+ uint32_t bit = (hash & 1) ? (1 << (sizeof(uint32_t) - 1)) : 0;
+
+ hash >>= 1;
+
+ hash += tolower(*key) + bit;
+ }
+
+ /* Keep the hash within the table limits */
+ return hash % size;
}
/*
@@ -97,26 +97,26 @@ hashfunc(const char *key, unsigned int size)
hashmap_t
hashmap_create(unsigned int nbuckets)
{
- struct hashmap_s* ptr;
+ struct hashmap_s *ptr;
- if (nbuckets == 0)
- return NULL;
+ if (nbuckets == 0)
+ return NULL;
- ptr = safecalloc(1, sizeof(struct hashmap_s));
- if (!ptr)
- return NULL;
+ ptr = safecalloc(1, sizeof(struct hashmap_s));
+ if (!ptr)
+ return NULL;
- ptr->size = nbuckets;
- ptr->buckets = safecalloc(nbuckets, sizeof(struct hashbucket_s));
- if (!ptr->buckets) {
- safefree(ptr);
- return NULL;
- }
+ ptr->size = nbuckets;
+ ptr->buckets = safecalloc(nbuckets, sizeof(struct hashbucket_s));
+ if (!ptr->buckets) {
+ safefree(ptr);
+ return NULL;
+ }
- /* This points to "one" past the end of the hashmap. */
- ptr->end_iterator = 0;
+ /* This points to "one" past the end of the hashmap. */
+ ptr->end_iterator = 0;
- return ptr;
+ return ptr;
}
/*
@@ -127,26 +127,26 @@ hashmap_create(unsigned int nbuckets)
* negative number is returned if "entry" was NULL
*/
static inline int
-delete_hashbucket(struct hashbucket_s* bucket)
+delete_hashbucket(struct hashbucket_s *bucket)
{
- struct hashentry_s *nextptr;
- struct hashentry_s *ptr;
+ struct hashentry_s *nextptr;
+ struct hashentry_s *ptr;
+
+ if (bucket == NULL || bucket->head == NULL)
+ return -EINVAL;
- if (bucket == NULL || bucket->head == NULL)
- return -EINVAL;
+ ptr = bucket->head;
+ while (ptr) {
+ nextptr = ptr->next;
- ptr = bucket->head;
- while (ptr) {
- nextptr = ptr->next;
-
- safefree(ptr->key);
- safefree(ptr->data);
- safefree(ptr);
+ safefree(ptr->key);
+ safefree(ptr->data);
+ safefree(ptr);
- ptr = nextptr;
- }
+ ptr = nextptr;
+ }
- return 0;
+ return 0;
}
/*
@@ -158,21 +158,21 @@ delete_hashbucket(struct hashbucket_s* bucket)
int
hashmap_delete(hashmap_t map)
{
- unsigned int i;
-
- if (map == NULL)
- return -EINVAL;
+ unsigned int i;
+
+ if (map == NULL)
+ return -EINVAL;
- for (i = 0; i != map->size; i++) {
- if (map->buckets[i].head != NULL) {
- delete_hashbucket(&map->buckets[i]);
- }
- }
+ for (i = 0; i != map->size; i++) {
+ if (map->buckets[i].head != NULL) {
+ delete_hashbucket(&map->buckets[i]);
+ }
+ }
- safefree(map->buckets);
- safefree(map);
+ safefree(map->buckets);
+ safefree(map);
- return 0;
+ return 0;
}
/*
@@ -186,57 +186,56 @@ hashmap_delete(hashmap_t map)
* negative number if there are errors
*/
int
-hashmap_insert(hashmap_t map, const char *key,
- const void *data, size_t len)
+hashmap_insert(hashmap_t map, const char *key, const void *data, size_t len)
{
- struct hashentry_s *ptr;
- int hash;
- char *key_copy;
- void *data_copy;
-
- assert(map != NULL);
- assert(key != NULL);
- assert(data != NULL);
- assert(len > 0);
-
- if (map == NULL || key == NULL)
- return -EINVAL;
- if (!data || len < 1)
- return -ERANGE;
-
- hash = hashfunc(key, map->size);
- if (hash < 0)
- return hash;
-
- /*
- * First make copies of the key and data in case there is a memory
- * problem later.
- */
- key_copy = safestrdup(key);
- if (!key_copy)
- return -ENOMEM;
-
- if (data) {
- data_copy = safemalloc(len);
- if (!data_copy) {
- safefree(key_copy);
- return -ENOMEM;
- }
- memcpy(data_copy, data, len);
- } else {
- data_copy = NULL;
- }
-
- ptr = safemalloc(sizeof(struct hashentry_s));
- if (!ptr) {
- safefree(key_copy);
- safefree(data_copy);
- return -ENOMEM;
- }
-
- ptr->key = key_copy;
- ptr->data = data_copy;
- ptr->len = len;
+ struct hashentry_s *ptr;
+ int hash;
+ char *key_copy;
+ void *data_copy;
+
+ assert(map != NULL);
+ assert(key != NULL);
+ assert(data != NULL);
+ assert(len > 0);
+
+ if (map == NULL || key == NULL)
+ return -EINVAL;
+ if (!data || len < 1)
+ return -ERANGE;
+
+ hash = hashfunc(key, map->size);
+ if (hash < 0)
+ return hash;
+
+ /*
+ * First make copies of the key and data in case there is a memory
+ * problem later.
+ */
+ key_copy = safestrdup(key);
+ if (!key_copy)
+ return -ENOMEM;
+
+ if (data) {
+ data_copy = safemalloc(len);
+ if (!data_copy) {
+ safefree(key_copy);
+ return -ENOMEM;
+ }
+ memcpy(data_copy, data, len);
+ } else {
+ data_copy = NULL;
+ }
+
+ ptr = safemalloc(sizeof(struct hashentry_s));
+ if (!ptr) {
+ safefree(key_copy);
+ safefree(data_copy);
+ return -ENOMEM;
+ }
+
+ ptr->key = key_copy;
+ ptr->data = data_copy;
+ ptr->len = len;
/*
* Now add the entry to the end of the bucket chain.
@@ -245,13 +244,13 @@ hashmap_insert(hashmap_t map, const char *key,
ptr->prev = map->buckets[hash].tail;
if (map->buckets[hash].tail)
map->buckets[hash].tail->next = ptr;
-
+
map->buckets[hash].tail = ptr;
if (!map->buckets[hash].head)
map->buckets[hash].head = ptr;
- map->end_iterator++;
- return 0;
+ map->end_iterator++;
+ return 0;
}
/*
@@ -262,15 +261,15 @@ hashmap_insert(hashmap_t map, const char *key,
hashmap_iter
hashmap_first(hashmap_t map)
{
- assert(map != NULL);
+ assert(map != NULL);
- if (!map)
- return -EINVAL;
+ if (!map)
+ return -EINVAL;
- if (map->end_iterator == 0)
- return -1;
- else
- return 0;
+ if (map->end_iterator == 0)
+ return -1;
+ else
+ return 0;
}
/*
@@ -282,16 +281,16 @@ hashmap_first(hashmap_t map)
int
hashmap_is_end(hashmap_t map, hashmap_iter iter)
{
- assert(map != NULL);
- assert(iter >= 0);
+ assert(map != NULL);
+ assert(iter >= 0);
- if (!map || iter < 0)
- return -EINVAL;
+ if (!map || iter < 0)
+ return -EINVAL;
- if (iter == map->end_iterator)
- return 1;
- else
- return 0;
+ if (iter == map->end_iterator)
+ return 1;
+ else
+ return 0;
}
/*
@@ -303,37 +302,37 @@ hashmap_is_end(hashmap_t map, hashmap_iter iter)
* an "end-iterator" if the key wasn't found
*/
hashmap_iter
-hashmap_find(hashmap_t map, const char* key)
+hashmap_find(hashmap_t map, const char *key)
{
- unsigned int i;
- hashmap_iter iter = 0;
- struct hashentry_s* ptr;
-
- assert(map != NULL);
- assert(key != NULL);
-
- if (!map || !key)
- return -EINVAL;
-
- /*
- * Loop through all the keys and look for the first occurrence
- * of a particular key.
- */
- for (i = 0; i != map->size; i++) {
- ptr = map->buckets[i].head;
-
- while (ptr) {
- if (strcasecmp(ptr->key, key) == 0) {
- /* Found it, so return the current count */
- return iter;
- }
-
- iter++;
- ptr = ptr->next;
- }
- }
-
- return iter;
+ unsigned int i;
+ hashmap_iter iter = 0;
+ struct hashentry_s *ptr;
+
+ assert(map != NULL);
+ assert(key != NULL);
+
+ if (!map || !key)
+ return -EINVAL;
+
+ /*
+ * Loop through all the keys and look for the first occurrence
+ * of a particular key.
+ */
+ for (i = 0; i != map->size; i++) {
+ ptr = map->buckets[i].head;
+
+ while (ptr) {
+ if (strcasecmp(ptr->key, key) == 0) {
+ /* Found it, so return the current count */
+ return iter;
+ }
+
+ iter++;
+ ptr = ptr->next;
+ }
+ }
+
+ return iter;
}
/*
@@ -343,38 +342,37 @@ hashmap_find(hashmap_t map, const char* key)
* negative upon error
*/
ssize_t
-hashmap_return_entry(hashmap_t map, hashmap_iter iter,
- char** key, void** data)
+hashmap_return_entry(hashmap_t map, hashmap_iter iter, char **key, void **data)
{
- unsigned int i;
- struct hashentry_s* ptr;
- hashmap_iter count = 0;
-
- assert(map != NULL);
- assert(iter >= 0);
- assert(iter != map->end_iterator);
- assert(key != NULL);
- assert(data != NULL);
-
- if (!map || iter < 0 || !key || !data)
- return -EINVAL;
-
- for (i = 0; i != map->size; i++) {
- ptr = map->buckets[i].head;
- while (ptr) {
- if (count == iter) {
- /* This is the data so return it */
- *key = ptr->key;
- *data = ptr->data;
- return ptr->len;
- }
-
- ptr = ptr->next;
- count++;
- }
- }
-
- return -EFAULT;
+ unsigned int i;
+ struct hashentry_s *ptr;
+ hashmap_iter count = 0;
+
+ assert(map != NULL);
+ assert(iter >= 0);
+ assert(iter != map->end_iterator);
+ assert(key != NULL);
+ assert(data != NULL);
+
+ if (!map || iter < 0 || !key || !data)
+ return -EINVAL;
+
+ for (i = 0; i != map->size; i++) {
+ ptr = map->buckets[i].head;
+ while (ptr) {
+ if (count == iter) {
+ /* This is the data so return it */
+ *key = ptr->key;
+ *data = ptr->data;
+ return ptr->len;
+ }
+
+ ptr = ptr->next;
+ count++;
+ }
+ }
+
+ return -EFAULT;
}
/*
@@ -387,29 +385,29 @@ hashmap_return_entry(hashmap_t map, hashmap_iter iter,
ssize_t
hashmap_search(hashmap_t map, const char *key)
{
- int hash;
- struct hashentry_s* ptr;
- ssize_t count = 0;
+ int hash;
+ struct hashentry_s *ptr;
+ ssize_t count = 0;
- if (map == NULL || key == NULL)
- return -EINVAL;
+ if (map == NULL || key == NULL)
+ return -EINVAL;
- hash = hashfunc(key, map->size);
- if (hash < 0)
- return hash;
+ hash = hashfunc(key, map->size);
+ if (hash < 0)
+ return hash;
- ptr = map->buckets[hash].head;
+ ptr = map->buckets[hash].head;
- /* All right, there is an entry here, now see if it's the one we want */
- while (ptr) {
- if (strcasecmp(ptr->key, key) == 0)
- ++count;
+ /* All right, there is an entry here, now see if it's the one we want */
+ while (ptr) {
+ if (strcasecmp(ptr->key, key) == 0)
+ ++count;
- /* This entry didn't contain the key; move to the next one */
- ptr = ptr->next;
- }
+ /* This entry didn't contain the key; move to the next one */
+ ptr = ptr->next;
+ }
- return count;
+ return count;
}
/*
@@ -421,30 +419,30 @@ hashmap_search(hashmap_t map, const char *key)
* length of data for the entry
*/
ssize_t
-hashmap_entry_by_key(hashmap_t map, const char* key, void** data)
+hashmap_entry_by_key(hashmap_t map, const char *key, void **data)
{
- int hash;
- struct hashentry_s* ptr;
+ int hash;
+ struct hashentry_s *ptr;
+
+ if (!map || !key || !data)
+ return -EINVAL;
- if (!map || !key || !data)
- return -EINVAL;
-
- hash = hashfunc(key, map->size);
- if (hash < 0)
- return hash;
+ hash = hashfunc(key, map->size);
+ if (hash < 0)
+ return hash;
- ptr = map->buckets[hash].head;
+ ptr = map->buckets[hash].head;
- while (ptr) {
- if (strcasecmp(ptr->key, key) == 0) {
- *data = ptr->data;
- return ptr->len;
- }
+ while (ptr) {
+ if (strcasecmp(ptr->key, key) == 0) {
+ *data = ptr->data;
+ return ptr->len;
+ }
- ptr = ptr->next;
- }
+ ptr = ptr->next;
+ }
- return 0;
+ return 0;
}
/*
@@ -458,26 +456,26 @@ hashmap_entry_by_key(hashmap_t map, const char* key, void** data)
ssize_t
hashmap_remove(hashmap_t map, const char *key)
{
- int hash;
- struct hashentry_s *ptr, *next;
- short int deleted = 0;
-
- if (map == NULL || key == NULL)
- return -EINVAL;
-
- hash = hashfunc(key, map->size);
- if (hash < 0)
- return hash;
-
- ptr = map->buckets[hash].head;
- while (ptr) {
- if (strcasecmp(ptr->key, key) == 0) {
- /*
- * Found the data, now need to remove everything
- * and update the hashmap.
- */
+ int hash;
+ struct hashentry_s *ptr, *next;
+ short int deleted = 0;
+
+ if (map == NULL || key == NULL)
+ return -EINVAL;
+
+ hash = hashfunc(key, map->size);
+ if (hash < 0)
+ return hash;
+
+ ptr = map->buckets[hash].head;
+ while (ptr) {
+ if (strcasecmp(ptr->key, key) == 0) {
+ /*
+ * Found the data, now need to remove everything
+ * and update the hashmap.
+ */
next = ptr->next;
-
+
if (ptr->prev)
ptr->prev->next = ptr->next;
if (ptr->next)
@@ -487,22 +485,22 @@ hashmap_remove(hashmap_t map, const char *key)
map->buckets[hash].head = ptr->next;
if (map->buckets[hash].tail == ptr)
map->buckets[hash].tail = ptr->prev;
-
- safefree(ptr->key);
- safefree(ptr->data);
- safefree(ptr);
-
- ++deleted;
- --map->end_iterator;
+
+ safefree(ptr->key);
+ safefree(ptr->data);
+ safefree(ptr);
+
+ ++deleted;
+ --map->end_iterator;
ptr = next;
- continue;
- }
+ continue;
+ }
- /* This entry didn't contain the key; move to the next one */
- ptr = ptr->next;
- }
+ /* This entry didn't contain the key; move to the next one */
+ ptr = ptr->next;
+ }
- /* The key was not found, so return 0 */
- return deleted;
+ /* The key was not found, so return 0 */
+ return deleted;
}
diff --git a/src/hashmap.h b/src/hashmap.h
index 69fe21a..aa376d4 100644
--- a/src/hashmap.h
+++ b/src/hashmap.h
@@ -1,4 +1,4 @@
-/* $Id: hashmap.h,v 1.3 2005-07-12 17:39:44 rjkaes Exp $
+/* $Id: hashmap.h,v 1.4 2005-08-15 03:54:31 rjkaes Exp $
*
* A hashmap implementation. The keys are case-insensitive NULL terminated
* strings, and the data is arbitrary lumps of data. Copies of both the
@@ -38,15 +38,15 @@ extern "C" {
* hash map. Sure, it's a pointer, but the struct is hidden in the C file.
* So, just use the hashmap_t like it's a cookie. :)
*/
-typedef struct hashmap_s* hashmap_t;
-typedef int hashmap_iter;
+ typedef struct hashmap_s *hashmap_t;
+ typedef int hashmap_iter;
/*
* hashmap_create() takes one argument, which is the number of buckets to
* use internally. hashmap_delete() is self explanatory.
*/
-extern hashmap_t hashmap_create(unsigned int nbuckets);
-extern int hashmap_delete(hashmap_t map);
+ extern hashmap_t hashmap_create(unsigned int nbuckets);
+ extern int hashmap_delete(hashmap_t map);
/*
* When the you insert a key/data pair into the hashmap it will the key
@@ -57,15 +57,15 @@ extern int hashmap_delete(hashmap_t map);
* Returns: negative on error
* 0 upon successful insert
*/
-extern int hashmap_insert(hashmap_t map, const char *key,
- const void *data, size_t len);
+ extern int hashmap_insert(hashmap_t map, const char *key,
+ const void *data, size_t len);
/*
* Get an iterator to the first entry.
*
* Returns: an negative value upon error.
*/
-extern hashmap_iter hashmap_first(hashmap_t map);
+ extern hashmap_iter hashmap_first(hashmap_t map);
/*
* Checks to see if the iterator is pointing at the "end" of the entries.
@@ -73,7 +73,7 @@ extern hashmap_iter hashmap_first(hashmap_t map);
* Returns: 1 if it is the end
* 0 otherwise
*/
-extern int hashmap_is_end(hashmap_t map, hashmap_iter iter);
+ extern int hashmap_is_end(hashmap_t map, hashmap_iter iter);
/*
* Return a "pointer" to the first instance of the particular key. It can
@@ -83,7 +83,7 @@ extern int hashmap_is_end(hashmap_t map, hashmap_iter iter);
* an "iterator" pointing at the first key
* an "end-iterator" if the key wasn't found
*/
-extern hashmap_iter hashmap_find(hashmap_t map, const char* key);
+ extern hashmap_iter hashmap_find(hashmap_t map, const char *key);
/*
* Retrieve the key/data associated with a particular iterator.
@@ -93,8 +93,8 @@ extern hashmap_iter hashmap_find(hashmap_t map, const char* key);
* Returns: the length of the data block upon success
* negative upon error
*/
-extern ssize_t hashmap_return_entry(hashmap_t map, hashmap_iter iter,
- char** key, void** data);
+ extern ssize_t hashmap_return_entry(hashmap_t map, hashmap_iter iter,
+ char **key, void **data);
/*
* Get the first entry (assuming there is more than one) for a particular
@@ -104,7 +104,8 @@ extern ssize_t hashmap_return_entry(hashmap_t map, hashmap_iter iter,
* zero if no entry is found
* length of data for the entry
*/
-extern ssize_t hashmap_entry_by_key(hashmap_t map, const char* key, void** data);
+ extern ssize_t hashmap_entry_by_key(hashmap_t map, const char *key,
+ void **data);
/*
* Searches for _any_ occurrances of "key" within the hashmap and returns the
@@ -114,7 +115,7 @@ extern ssize_t hashmap_entry_by_key(hashmap_t map, const char* key, void** data)
* zero if no key is found
* count found (positive value)
*/
-extern ssize_t hashmap_search(hashmap_t map, const char *key);
+ extern ssize_t hashmap_search(hashmap_t map, const char *key);
/*
* Go through the hashmap and remove the particular key.
@@ -124,10 +125,9 @@ extern ssize_t hashmap_search(hashmap_t map, const char *key);
* 0 if the key was not found
* positive count of entries deleted
*/
-extern ssize_t hashmap_remove(hashmap_t map, const char *key);
+ extern ssize_t hashmap_remove(hashmap_t map, const char *key);
#if defined(__cplusplus)
}
-#endif /* C++ */
-
-#endif /* _HASHMAP_H */
+#endif /* C++ */
+#endif /* _HASHMAP_H */
diff --git a/src/heap.c b/src/heap.c
index d358746..6a256a9 100644
--- a/src/heap.c
+++ b/src/heap.c
@@ -1,4 +1,4 @@
-/* $Id: heap.c,v 1.9 2005-07-12 17:39:44 rjkaes Exp $
+/* $Id: heap.c,v 1.10 2005-08-15 03:54:31 rjkaes Exp $
*
* Debugging versions of various heap related functions are combined
* here. The debugging versions include assertions and also print
@@ -25,70 +25,70 @@
void *
debugging_calloc(size_t nmemb, size_t size, const char *file,
- unsigned long line)
+ unsigned long line)
{
- void *ptr;
+ void *ptr;
- assert(nmemb > 0);
- assert(size > 0);
+ assert(nmemb > 0);
+ assert(size > 0);
- ptr = calloc(nmemb, size);
- fprintf(stderr, "{calloc: %p:%u x %u} %s:%lu\n", ptr, nmemb, size, file,
- line);
- return ptr;
+ ptr = calloc(nmemb, size);
+ fprintf(stderr, "{calloc: %p:%u x %u} %s:%lu\n", ptr, nmemb, size, file,
+ line);
+ return ptr;
}
void *
debugging_malloc(size_t size, const char *file, unsigned long line)
{
- void *ptr;
+ void *ptr;
- assert(size > 0);
+ assert(size > 0);
- ptr = malloc(size);
- fprintf(stderr, "{malloc: %p:%u} %s:%lu\n", ptr, size, file, line);
- return ptr;
+ ptr = malloc(size);
+ fprintf(stderr, "{malloc: %p:%u} %s:%lu\n", ptr, size, file, line);
+ return ptr;
}
void *
debugging_realloc(void *ptr, size_t size, const char *file, unsigned long line)
{
- void *newptr;
-
- assert(size > 0);
-
- newptr = realloc(ptr, size);
- fprintf(stderr, "{realloc: %p -> %p:%u} %s:%lu\n", ptr, newptr, size,
- file, line);
- return newptr;
+ void *newptr;
+
+ assert(size > 0);
+
+ newptr = realloc(ptr, size);
+ fprintf(stderr, "{realloc: %p -> %p:%u} %s:%lu\n", ptr, newptr, size,
+ file, line);
+ return newptr;
}
void
debugging_free(void *ptr, const char *file, unsigned long line)
{
- fprintf(stderr, "{free: %p} %s:%lu\n", ptr, file, line);
+ fprintf(stderr, "{free: %p} %s:%lu\n", ptr, file, line);
- if (ptr != NULL)
- free(ptr);
- return;
+ if (ptr != NULL)
+ free(ptr);
+ return;
}
-char*
-debugging_strdup(const char* s, const char* file, unsigned long line)
+char *
+debugging_strdup(const char *s, const char *file, unsigned long line)
{
- char* ptr;
- size_t len;
+ char *ptr;
+ size_t len;
- assert(s != NULL);
+ assert(s != NULL);
- len = strlen(s) + 1;
- ptr = malloc(len);
- if (!ptr)
- return NULL;
- memcpy(ptr, s, len);
+ len = strlen(s) + 1;
+ ptr = malloc(len);
+ if (!ptr)
+ return NULL;
+ memcpy(ptr, s, len);
- fprintf(stderr, "{strdup: %p:%u} %s:%lu\n", ptr, len, file, line);
- return ptr;
+ fprintf(stderr, "{strdup: %p:%u} %s:%lu\n", ptr, len, file, line);
+ return ptr;
}
/*
@@ -99,51 +99,50 @@ debugging_strdup(const char* s, const char* file, unsigned long line)
* want to look into something like MM (Shared Memory Library) for a better
* solution.
*/
-void*
+void *
malloc_shared_memory(size_t size)
{
- int fd;
- void* ptr;
- char buffer[32];
+ int fd;
+ void *ptr;
+ char buffer[32];
- static char* shared_file = "/tmp/tinyproxy.shared.XXXXXX";
+ static char *shared_file = "/tmp/tinyproxy.shared.XXXXXX";
- assert(size > 0);
+ assert(size > 0);
- strlcpy(buffer, shared_file, sizeof(buffer));
+ strlcpy(buffer, shared_file, sizeof(buffer));
- if ((fd = mkstemp(buffer)) == -1)
- return MAP_FAILED;
- unlink(buffer);
+ if ((fd = mkstemp(buffer)) == -1)
+ return MAP_FAILED;
+ unlink(buffer);
- if (ftruncate(fd, size) == -1)
- return MAP_FAILED;
- ptr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if (ftruncate(fd, size) == -1)
+ return MAP_FAILED;
+ ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- return ptr;
+ return ptr;
}
/*
* Allocate a block of memory from the "shared" region an initialize it to
* zero.
*/
-void*
+void *
calloc_shared_memory(size_t nmemb, size_t size)
{
- void* ptr;
- long length;
+ void *ptr;
+ long length;
- assert(nmemb > 0);
- assert(size > 0);
+ assert(nmemb > 0);
+ assert(size > 0);
- length = nmemb * size;
+ length = nmemb * size;
- ptr = malloc_shared_memory(length);
- if (ptr == MAP_FAILED)
- return ptr;
+ ptr = malloc_shared_memory(length);
+ if (ptr == MAP_FAILED)
+ return ptr;
- memset(ptr, 0, length);
+ memset(ptr, 0, length);
- return ptr;
+ return ptr;
}
-
diff --git a/src/heap.h b/src/heap.h
index 7bf9f5c..292d989 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -1,4 +1,4 @@
-/* $Id: heap.h,v 1.5 2005-07-12 17:39:44 rjkaes Exp $
+/* $Id: heap.h,v 1.6 2005-08-15 03:54:31 rjkaes Exp $
*
* See 'heap.c' for a detailed description.
*
@@ -24,14 +24,14 @@
#ifndef NDEBUG
extern void *debugging_calloc(size_t nmemb, size_t size, const char *file,
- unsigned long line);
+ unsigned long line);
extern void *debugging_malloc(size_t size, const char *file,
- unsigned long line);
+ unsigned long line);
extern void debugging_free(void *ptr, const char *file, unsigned long line);
extern void *debugging_realloc(void *ptr, size_t size, const char *file,
- unsigned long line);
-extern char *debugging_strdup(const char* s, const char* file,
- unsigned long line);
+ unsigned long line);
+extern char *debugging_strdup(const char *s, const char *file,
+ unsigned long line);
# define safecalloc(x, y) debugging_calloc(x, y, __FILE__, __LINE__)
# define safemalloc(x) debugging_malloc(x, __FILE__, __LINE__)
@@ -57,7 +57,7 @@ free(*__safefree_tmp); \
/*
* Allocate memory from the "shared" region of memory.
*/
-extern void* malloc_shared_memory(size_t size);
-extern void* calloc_shared_memory(size_t nmemb, size_t size);
+extern void *malloc_shared_memory(size_t size);
+extern void *calloc_shared_memory(size_t nmemb, size_t size);
#endif
diff --git a/src/htmlerror.c b/src/htmlerror.c
index d02eae8..afc1e63 100644
--- a/src/htmlerror.c
+++ b/src/htmlerror.c
@@ -1,4 +1,4 @@
-/* $Id: htmlerror.c,v 1.7 2003-08-01 00:14:34 rjkaes Exp $
+/* $Id: htmlerror.c,v 1.8 2005-08-15 03:54:31 rjkaes Exp $
*
* This file contains source code for the handling and display of
* HTML error pages with variable substitution.
@@ -29,73 +29,77 @@
/*
* Add an error number -> filename mapping to the errorpages list.
*/
-#define ERRORNUM_BUFSIZE 8 /* this is more than required */
+#define ERRORNUM_BUFSIZE 8 /* this is more than required */
#define ERRPAGES_BUCKETCOUNT 16
int
-add_new_errorpage(char *filepath, unsigned int errornum) {
- char errornbuf[ERRORNUM_BUFSIZE];
+add_new_errorpage(char *filepath, unsigned int errornum)
+{
+ char errornbuf[ERRORNUM_BUFSIZE];
- config.errorpages = hashmap_create(ERRPAGES_BUCKETCOUNT);
- if (!config.errorpages)
- return(-1);
+ config.errorpages = hashmap_create(ERRPAGES_BUCKETCOUNT);
+ if (!config.errorpages)
+ return (-1);
- snprintf(errornbuf, ERRORNUM_BUFSIZE, "%u", errornum);
+ snprintf(errornbuf, ERRORNUM_BUFSIZE, "%u", errornum);
- if (hashmap_insert(config.errorpages, errornbuf,
- filepath, strlen(filepath) + 1) < 0)
- return(-1);
+ if (hashmap_insert(config.errorpages, errornbuf,
+ filepath, strlen(filepath) + 1) < 0)
+ return (-1);
- return(0);
+ return (0);
}
/*
* Get the file appropriate for a given error.
*/
-static char*
-get_html_file(unsigned int errornum) {
- hashmap_iter result_iter;
- char errornbuf[ERRORNUM_BUFSIZE];
- char *key;
- static char *val;
+static char *
+get_html_file(unsigned int errornum)
+{
+ hashmap_iter result_iter;
+ char errornbuf[ERRORNUM_BUFSIZE];
+ char *key;
+ static char *val;
- assert(errornum >= 100 && errornum < 1000);
+ assert(errornum >= 100 && errornum < 1000);
- if (!config.errorpages) return(config.errorpage_undef);
+ if (!config.errorpages)
+ return (config.errorpage_undef);
- snprintf(errornbuf, ERRORNUM_BUFSIZE, "%u", errornum);
+ snprintf(errornbuf, ERRORNUM_BUFSIZE, "%u", errornum);
- result_iter = hashmap_find(config.errorpages, errornbuf);
+ result_iter = hashmap_find(config.errorpages, errornbuf);
- if (hashmap_is_end(config.errorpages, result_iter))
- return(config.errorpage_undef);
+ if (hashmap_is_end(config.errorpages, result_iter))
+ return (config.errorpage_undef);
- if (hashmap_return_entry(config.errorpages, result_iter,
- &key, (void **)&val) < 0)
- return(config.errorpage_undef);
+ if (hashmap_return_entry(config.errorpages, result_iter,
+ &key, (void **)&val) < 0)
+ return (config.errorpage_undef);
- return(val);
+ return (val);
}
/*
* Look up the value for a variable.
*/
-static char*
-lookup_variable(struct conn_s *connptr, char *varname) {
- hashmap_iter result_iter;
- char *key;
- static char *data;
+static char *
+lookup_variable(struct conn_s *connptr, char *varname)
+{
+ hashmap_iter result_iter;
+ char *key;
+ static char *data;
- result_iter = hashmap_find(connptr->error_variables, varname);
+ result_iter = hashmap_find(connptr->error_variables, varname);
- if (hashmap_is_end(connptr->error_variables, result_iter))
- return(NULL);
+ if (hashmap_is_end(connptr->error_variables, result_iter))
+ return (NULL);
- if (hashmap_return_entry(connptr->error_variables, result_iter,
- &key, (void **)&data) < 0)
- return(NULL);
+ if (hashmap_return_entry(connptr->error_variables, result_iter,
+ &key, (void **)&data) < 0)
+ return (NULL);
- return(data);
+ return (data);
}
#define HTML_BUFSIZE 4096
@@ -104,66 +108,75 @@ lookup_variable(struct conn_s *connptr, char *varname) {
* Send an already-opened file to the client with variable substitution.
*/
int
-send_html_file(FILE *infile, struct conn_s *connptr) {
- char inbuf[HTML_BUFSIZE], *varstart = NULL, *p;
- char *varval;
- int in_variable = 0, writeret;
-
- while(fgets(inbuf, HTML_BUFSIZE, infile) != NULL) {
- for (p = inbuf; *p; p++) {
- switch(*p) {
- case '}':
- if(in_variable) {
- *p = '\0';
- if(!(varval = lookup_variable(connptr, varstart)))
- varval = "(unknown)";
- writeret = write_message(connptr->client_fd, "%s",
- varval);
- if(writeret) return(writeret);
- in_variable = 0;
- } else {
- writeret = write_message(connptr->client_fd, "%c", *p);
- if (writeret) return(writeret);
- }
- break;
- case '{':
- /* a {{ will print a single {. If we are NOT
- * already in a { variable, then proceed with
- * setup. If we ARE already in a { variable,
- * this code will fallthrough to the code that
- * just dumps a character to the client fd.
- */
- if(!in_variable) {
- varstart = p+1;
- in_variable++;
- } else
- in_variable = 0;
- default:
- if(!in_variable) {
- writeret = write_message(connptr->client_fd, "%c",
- *p);
- if(writeret) return(writeret);
- }
-
- }
- }
- in_variable = 0;
- }
- return(0);
+send_html_file(FILE * infile, struct conn_s *connptr)
+{
+ char inbuf[HTML_BUFSIZE], *varstart = NULL, *p;
+ char *varval;
+ int in_variable = 0, writeret;
+
+ while (fgets(inbuf, HTML_BUFSIZE, infile) != NULL) {
+ for (p = inbuf; *p; p++) {
+ switch (*p) {
+ case '}':
+ if (in_variable) {
+ *p = '\0';
+ if (!
+ (varval =
+ lookup_variable(connptr,
+ varstart)))
+ varval = "(unknown)";
+ writeret =
+ write_message(connptr->client_fd,
+ "%s", varval);
+ if (writeret)
+ return (writeret);
+ in_variable = 0;
+ } else {
+ writeret =
+ write_message(connptr->client_fd,
+ "%c", *p);
+ if (writeret)
+ return (writeret);
+ }
+ break;
+ case '{':
+ /* a {{ will print a single {. If we are NOT
+ * already in a { variable, then proceed with
+ * setup. If we ARE already in a { variable,
+ * this code will fallthrough to the code that
+ * just dumps a character to the client fd.
+ */
+ if (!in_variable) {
+ varstart = p + 1;
+ in_variable++;
+ } else
+ in_variable = 0;
+ default:
+ if (!in_variable) {
+ writeret =
+ write_message(connptr->client_fd,
+ "%c", *p);
+ if (writeret)
+ return (writeret);
+ }
+
+ }
+ }
+ in_variable = 0;
+ }
+ return (0);
}
int
-send_http_headers(struct conn_s *connptr, int code, char *message) {
- char *headers = \
- "HTTP/1.0 %d %s\r\n" \
- "Server: %s/%s\r\n" \
- "Content-Type: text/html\r\n" \
- "Connection: close\r\n" \
- "\r\n";
-
- return(write_message(connptr->client_fd, headers,
- code, message,
- PACKAGE, VERSION));
+send_http_headers(struct conn_s *connptr, int code, char *message)
+{
+ char *headers =
+ "HTTP/1.0 %d %s\r\n"
+ "Server: %s/%s\r\n"
+ "Content-Type: text/html\r\n" "Connection: close\r\n" "\r\n";
+
+ return (write_message(connptr->client_fd, headers,
+ code, message, PACKAGE, VERSION));
}
/*
@@ -172,33 +185,32 @@ send_http_headers(struct conn_s *connptr, int code, char *message) {
int
send_http_error_message(struct conn_s *connptr)
{
- char *error_file;
- FILE *infile;
- int ret;
- char *fallback_error = \
- "<html><head><title>%s</title></head>" \
- "<body><blockquote><i>%s %s</i><br>" \
- "The page you requested was unavailable. The error code is listed " \
- "below. In addition, the HTML file which has been configured as the " \
- "page to be displayed when an error of this type was unavailable, " \
- "with the error code %d (%s). Please contact your administrator." \
- "<center>%s</center>" \
- "</body></html>" \
- "\r\n";
-
- send_http_headers(connptr, connptr->error_number, connptr->error_string);
-
- error_file = get_html_file(connptr->error_number);
- if(!(infile = fopen(error_file, "r")))
- return(write_message(connptr->client_fd, fallback_error,
- connptr->error_string,
- PACKAGE, VERSION,
- errno, strerror(errno),
- connptr->error_string));
-
- ret = send_html_file(infile, connptr);
- fclose(infile);
- return(ret);
+ char *error_file;
+ FILE *infile;
+ int ret;
+ char *fallback_error =
+ "<html><head><title>%s</title></head>"
+ "<body><blockquote><i>%s %s</i><br>"
+ "The page you requested was unavailable. The error code is listed "
+ "below. In addition, the HTML file which has been configured as the "
+ "page to be displayed when an error of this type was unavailable, "
+ "with the error code %d (%s). Please contact your administrator."
+ "<center>%s</center>" "</body></html>" "\r\n";
+
+ send_http_headers(connptr, connptr->error_number,
+ connptr->error_string);
+
+ error_file = get_html_file(connptr->error_number);
+ if (!(infile = fopen(error_file, "r")))
+ return (write_message(connptr->client_fd, fallback_error,
+ connptr->error_string,
+ PACKAGE, VERSION,
+ errno, strerror(errno),
+ connptr->error_string));
+
+ ret = send_html_file(infile, connptr);
+ fclose(infile);
+ return (ret);
}
/*
@@ -207,18 +219,20 @@ send_http_error_message(struct conn_s *connptr)
#define ERRVAR_BUCKETCOUNT 16
-int
-add_error_variable(struct conn_s *connptr, char *key, char *val)
+int
+add_error_variable(struct conn_s *connptr, char *key, char *val)
{
- if(!connptr->error_variables)
- if (!(connptr->error_variables = hashmap_create(ERRVAR_BUCKETCOUNT)))
- return(-1);
+ if (!connptr->error_variables)
+ if (!
+ (connptr->error_variables =
+ hashmap_create(ERRVAR_BUCKETCOUNT)))
+ return (-1);
- if (hashmap_insert(connptr->error_variables, key, val,
- strlen(val) + 1) < 0)
- return(-1);
+ if (hashmap_insert(connptr->error_variables, key, val,
+ strlen(val) + 1) < 0)
+ return (-1);
- return(0);
+ return (0);
}
#define ADD_VAR_RET(x, y) if(y) { if(add_error_variable(connptr, x, y) == -1) return(-1); }
@@ -227,46 +241,48 @@ add_error_variable(struct conn_s *connptr, char *key, char *val)
* Set some standard variables used by all HTML pages
*/
int
-add_standard_vars(struct conn_s *connptr) {
- char timebuf[30];
- time_t global_time = time(NULL);
-
- strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT",
- gmtime(&global_time));
-
- ADD_VAR_RET("request", connptr->request_line);
- ADD_VAR_RET("cause", connptr->error_string);
- ADD_VAR_RET("clientip", connptr->client_ip_addr);
- ADD_VAR_RET("clienthost", connptr->client_string_addr);
- ADD_VAR_RET("version", VERSION);
- ADD_VAR_RET("package", PACKAGE);
- ADD_VAR_RET("date", timebuf);
- return(0);
+add_standard_vars(struct conn_s *connptr)
+{
+ char timebuf[30];
+ time_t global_time = time(NULL);
+
+ strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT",
+ gmtime(&global_time));
+
+ ADD_VAR_RET("request", connptr->request_line);
+ ADD_VAR_RET("cause", connptr->error_string);
+ ADD_VAR_RET("clientip", connptr->client_ip_addr);
+ ADD_VAR_RET("clienthost", connptr->client_string_addr);
+ ADD_VAR_RET("version", VERSION);
+ ADD_VAR_RET("package", PACKAGE);
+ ADD_VAR_RET("date", timebuf);
+ return (0);
}
/*
* Add the error information to the conn structure.
*/
int
-indicate_http_error(struct conn_s* connptr, int number, char *message, ...)
+indicate_http_error(struct conn_s *connptr, int number, char *message, ...)
{
- va_list ap;
- char *key, *val;
+ va_list ap;
+ char *key, *val;
+
+ va_start(ap, message);
- va_start(ap, message);
+ while ((key = va_arg(ap, char *))) {
+ val = va_arg(ap, char *);
- while((key = va_arg(ap, char *))) {
- val = va_arg(ap, char *);
- if(add_error_variable(connptr, key, val) == -1) {
- va_end(ap);
- return(-1);
- }
- }
+ if (add_error_variable(connptr, key, val) == -1) {
+ va_end(ap);
+ return (-1);
+ }
+ }
- connptr->error_number = number;
- connptr->error_string = safestrdup(message);
+ connptr->error_number = number;
+ connptr->error_string = safestrdup(message);
- va_end(ap);
+ va_end(ap);
- return(add_standard_vars(connptr));
+ return (add_standard_vars(connptr));
}
diff --git a/src/htmlerror.h b/src/htmlerror.h
index 63202b4..1dca430 100644
--- a/src/htmlerror.h
+++ b/src/htmlerror.h
@@ -1,4 +1,4 @@
-/* $Id: htmlerror.h,v 1.2 2003-03-14 22:45:59 rjkaes Exp $
+/* $Id: htmlerror.h,v 1.3 2005-08-15 03:54:31 rjkaes Exp $
*
* Contains header declarations for the HTML error functions in
* htmlerror.c
@@ -24,10 +24,11 @@ struct conn_s;
extern int add_new_errorpage(char *filepath, unsigned int errornum);
extern int send_http_error_message(struct conn_s *connptr);
-extern int indicate_http_error(struct conn_s *connptr, int number, char *message, ...);
+extern int indicate_http_error(struct conn_s *connptr, int number,
+ char *message, ...);
extern int add_error_variable(struct conn_s *connptr, char *key, char *val);
-extern int send_html_file(FILE *infile, struct conn_s *connptr);
+extern int send_html_file(FILE * infile, struct conn_s *connptr);
extern int send_http_headers(struct conn_s *connptr, int code, char *message);
extern int add_standard_vars(struct conn_s *connptr);
-#endif /* !TINYPROXY_HTMLERROR_H */
+#endif /* !TINYPROXY_HTMLERROR_H */
diff --git a/src/http_message.c b/src/http_message.c
index 8e454fb..35bfa1c 100644
--- a/src/http_message.c
+++ b/src/http_message.c
@@ -1,4 +1,4 @@
-/* $Id: http_message.c,v 1.5 2005-07-12 17:39:44 rjkaes Exp $
+/* $Id: http_message.c,v 1.6 2005-08-15 03:54:31 rjkaes Exp $
*
* See 'http_message.h' for a detailed description.
*
@@ -28,28 +28,28 @@
* still in use---bad things would happen.
*/
struct http_message_s {
- /* Response string and code supplied on the HTTP status line */
- struct {
- const char* string;
- int code;
- } response;
-
- /*
- * A group of headers to be sent with this message. Right now
- * the strings are referenced through pointers in an array.
- * I might change this to a vector in the future.
- */
- struct {
- char** strings;
- unsigned int total;
- unsigned int used;
- } headers;
-
- /* Body of the message (most likely an HTML message) */
- struct {
- const char* text;
- size_t length;
- } body;
+ /* Response string and code supplied on the HTTP status line */
+ struct {
+ const char *string;
+ int code;
+ } response;
+
+ /*
+ * A group of headers to be sent with this message. Right now
+ * the strings are referenced through pointers in an array.
+ * I might change this to a vector in the future.
+ */
+ struct {
+ char **strings;
+ unsigned int total;
+ unsigned int used;
+ } headers;
+
+ /* Body of the message (most likely an HTML message) */
+ struct {
+ const char *text;
+ size_t length;
+ } body;
};
/*
@@ -60,12 +60,16 @@ struct http_message_s {
static int
is_http_message_valid(http_message_t msg)
{
- if (msg == NULL) return 0;
- if (msg->headers.strings == NULL) return 0;
- if (msg->response.string == NULL) return 0;
- if (msg->response.code < 1 || msg->response.code > 999) return 0;
-
- return 1;
+ if (msg == NULL)
+ return 0;
+ if (msg->headers.strings == NULL)
+ return 0;
+ if (msg->response.string == NULL)
+ return 0;
+ if (msg->response.code < 1 || msg->response.code > 999)
+ return 0;
+
+ return 1;
}
/* Initially allocate space for 128 headers */
@@ -76,32 +80,32 @@ is_http_message_valid(http_message_t msg)
* If memory could not be allocated, return a NULL.
*/
http_message_t
-http_message_create(int response_code, const char* response_string)
+http_message_create(int response_code, const char *response_string)
{
- http_message_t msg;
- int ret;
-
- msg = safecalloc(1, sizeof(struct http_message_s));
- if (msg == NULL)
- return NULL;
-
- msg->headers.strings = safecalloc(NUMBER_OF_HEADERS, sizeof(char*));
- if (msg->headers.strings == NULL) {
- safefree(msg);
- return NULL;
- }
-
- msg->headers.total = NUMBER_OF_HEADERS;
-
- /* Store the HTTP response information in the structure */
- ret = http_message_set_response(msg, response_code, response_string);
- if (IS_HTTP_MSG_ERROR(ret)) {
- safefree(msg->headers.strings);
- safefree(msg);
- return NULL;
- }
-
- return msg;
+ http_message_t msg;
+ int ret;
+
+ msg = safecalloc(1, sizeof(struct http_message_s));
+ if (msg == NULL)
+ return NULL;
+
+ msg->headers.strings = safecalloc(NUMBER_OF_HEADERS, sizeof(char *));
+ if (msg->headers.strings == NULL) {
+ safefree(msg);
+ return NULL;
+ }
+
+ msg->headers.total = NUMBER_OF_HEADERS;
+
+ /* Store the HTTP response information in the structure */
+ ret = http_message_set_response(msg, response_code, response_string);
+ if (IS_HTTP_MSG_ERROR(ret)) {
+ safefree(msg->headers.strings);
+ safefree(msg);
+ return NULL;
+ }
+
+ return msg;
}
/*
@@ -112,16 +116,17 @@ http_message_create(int response_code, const char* response_string)
int
http_message_destroy(http_message_t msg)
{
- assert(msg != NULL);
- assert(msg->headers.strings != NULL);
+ assert(msg != NULL);
+ assert(msg->headers.strings != NULL);
- /* Check for valid arguments */
- if (msg == NULL) return -EFAULT;
+ /* Check for valid arguments */
+ if (msg == NULL)
+ return -EFAULT;
- if (msg->headers.strings != NULL)
- safefree(msg->headers.strings);
- safefree(msg);
- return 0;
+ if (msg->headers.strings != NULL)
+ safefree(msg->headers.strings);
+ safefree(msg);
+ return 0;
}
/*
@@ -130,81 +135,89 @@ http_message_destroy(http_message_t msg)
*/
int
http_message_set_response(http_message_t msg,
- int response_code,
- const char* response_string)
+ int response_code, const char *response_string)
{
- /* Check for valid arguments */
- if (msg == NULL) return -EFAULT;
- if (response_code < 1 || response_code > 999) return -EINVAL;
- if (response_string == NULL) return -EINVAL;
- if (strlen(response_string) == 0) return -EINVAL;
-
- msg->response.code = response_code;
- msg->response.string = response_string;
-
- return 0;
+ /* Check for valid arguments */
+ if (msg == NULL)
+ return -EFAULT;
+ if (response_code < 1 || response_code > 999)
+ return -EINVAL;
+ if (response_string == NULL)
+ return -EINVAL;
+ if (strlen(response_string) == 0)
+ return -EINVAL;
+
+ msg->response.code = response_code;
+ msg->response.string = response_string;
+
+ return 0;
}
/*
* Set the HTTP message body.
*/
int
-http_message_set_body(http_message_t msg, const char* body, size_t len)
+http_message_set_body(http_message_t msg, const char *body, size_t len)
{
- /* Check for valid arguments */
- if (msg == NULL) return -EFAULT;
- if (body == NULL) return -EINVAL;
- if (len == 0) return -EINVAL;
-
- msg->body.text = body;
- msg->body.length = len;
-
- return 0;
+ /* Check for valid arguments */
+ if (msg == NULL)
+ return -EFAULT;
+ if (body == NULL)
+ return -EINVAL;
+ if (len == 0)
+ return -EINVAL;
+
+ msg->body.text = body;
+ msg->body.length = len;
+
+ return 0;
}
/*
* Add headers to the structure.
*/
int
-http_message_add_headers(http_message_t msg, char** headers,
- int num_headers)
+http_message_add_headers(http_message_t msg, char **headers, int num_headers)
{
- char** new_headers;
- int i;
-
- /* Check for valid arguments */
- if (msg == NULL) return -EFAULT;
- if (headers == NULL) return -EINVAL;
- if (num_headers < 1) return -EINVAL;
-
- /*
- * If the number of headers to add is greater than the space
- * available, reallocate the memory.
- */
- if (msg->headers.used + num_headers > msg->headers.total) {
- new_headers = safecalloc(msg->headers.total * 2,
- sizeof(char*));
- if (new_headers == NULL)
- return -ENOMEM;
-
- /* Copy the array */
- for (i = 0; i != msg->headers.used; ++i)
- new_headers[i] = msg->headers.strings[i];
-
- /* Remove the old array and replace it with the new array */
- safefree(msg->headers.strings);
- msg->headers.strings = new_headers;
- msg->headers.total *= 2;
- }
-
- /*
- * Add the new headers to the structure
- */
- for (i = 0; i != num_headers; ++i)
- msg->headers.strings[i + msg->headers.used] = headers[i];
- msg->headers.used += num_headers;
-
- return 0;
+ char **new_headers;
+ int i;
+
+ /* Check for valid arguments */
+ if (msg == NULL)
+ return -EFAULT;
+ if (headers == NULL)
+ return -EINVAL;
+ if (num_headers < 1)
+ return -EINVAL;
+
+ /*
+ * If the number of headers to add is greater than the space
+ * available, reallocate the memory.
+ */
+ if (msg->headers.used + num_headers > msg->headers.total) {
+ new_headers = safecalloc(msg->headers.total * 2,
+ sizeof(char *));
+ if (new_headers == NULL)
+ return -ENOMEM;
+
+ /* Copy the array */
+ for (i = 0; i != msg->headers.used; ++i)
+ new_headers[i] = msg->headers.strings[i];
+
+ /* Remove the old array and replace it with the new array */
+ safefree(msg->headers.strings);
+ msg->headers.strings = new_headers;
+ msg->headers.total *= 2;
+ }
+
+ /*
+ * Add the new headers to the structure
+ */
+ for (i = 0; i != num_headers; ++i)
+ msg->headers.strings[i + msg->headers.used] = headers[i];
+ msg->headers.used += num_headers;
+
+ return 0;
}
/*
@@ -213,40 +226,43 @@ http_message_add_headers(http_message_t msg, char** headers,
int
http_message_send(http_message_t msg, int fd)
{
- char timebuf[30];
- time_t global_time;
- unsigned int i;
+ char timebuf[30];
+ time_t global_time;
+ unsigned int i;
- assert(is_http_message_valid(msg));
+ assert(is_http_message_valid(msg));
- /* Check for valid arguments */
- if (msg == NULL) return -EFAULT;
- if (fd < 1) return -EBADF;
- if (!is_http_message_valid(msg)) return -EINVAL;
+ /* Check for valid arguments */
+ if (msg == NULL)
+ return -EFAULT;
+ if (fd < 1)
+ return -EBADF;
+ if (!is_http_message_valid(msg))
+ return -EINVAL;
- /* Write the response line */
- write_message(fd, "HTTP/1.0 %d %s\r\n",
- msg->response.code, msg->response.string);
+ /* Write the response line */
+ write_message(fd, "HTTP/1.0 %d %s\r\n",
+ msg->response.code, msg->response.string);
- /* Go through all the headers */
- for (i = 0; i != msg->headers.used; ++i)
- write_message(fd, "%s\r\n", msg->headers.strings[i]);
+ /* Go through all the headers */
+ for (i = 0; i != msg->headers.used; ++i)
+ write_message(fd, "%s\r\n", msg->headers.strings[i]);
- /* Output the date */
- global_time = time(NULL);
- strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT",
- gmtime(&global_time));
- write_message(fd, "Date: %s\r\n", timebuf);
+ /* Output the date */
+ global_time = time(NULL);
+ strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT",
+ gmtime(&global_time));
+ write_message(fd, "Date: %s\r\n", timebuf);
- /* Output the content-length */
- write_message(fd, "Content-length: %u\r\n", msg->body.length);
+ /* Output the content-length */
+ write_message(fd, "Content-length: %u\r\n", msg->body.length);
- /* Write the separator between the headers and body */
- safe_write(fd, "\r\n", 2);
+ /* Write the separator between the headers and body */
+ safe_write(fd, "\r\n", 2);
- /* If there's a body, send it! */
- if (msg->body.length > 0)
- safe_write(fd, msg->body.text, msg->body.length);
+ /* If there's a body, send it! */
+ if (msg->body.length > 0)
+ safe_write(fd, msg->body.text, msg->body.length);
- return 0;
+ return 0;
}
diff --git a/src/http_message.h b/src/http_message.h
index deaf9d5..fe8c798 100644
--- a/src/http_message.h
+++ b/src/http_message.h
@@ -1,4 +1,4 @@
-/* $Id: http_message.h,v 1.2 2005-07-12 17:39:44 rjkaes Exp $
+/* $Id: http_message.h,v 1.3 2005-08-15 03:54:31 rjkaes Exp $
*
* HTTP Message API
* ----------------
@@ -55,7 +55,7 @@ typedef struct http_message_s *http_message_t;
/* Initialize the internal structure of the HTTP message */
extern http_message_t http_message_create(int response_code,
- const char* response_string);
+ const char *response_string);
/* Free up an _internal_ resources */
extern int http_message_destroy(http_message_t msg);
@@ -72,10 +72,10 @@ extern int http_message_send(http_message_t msg, int fd);
* add a new set of headers.
*/
extern int http_message_set_body(http_message_t msg,
- const char* body, size_t len);
+ const char *body, size_t len);
extern int http_message_set_response(http_message_t msg,
- int response_code,
- const char* response_string);
+ int response_code,
+ const char *response_string);
/*
* Set the headers for this HTTP message. Each string must be NUL ('\0')
@@ -84,7 +84,6 @@ extern int http_message_set_response(http_message_t msg,
* sent.
*/
extern int http_message_add_headers(http_message_t msg,
- char** headers,
- int num_headers);
+ char **headers, int num_headers);
-#endif /* _TINYPROXY_HTTP_MESSAGE_H_ */
+#endif /* _TINYPROXY_HTTP_MESSAGE_H_ */
diff --git a/src/log.c b/src/log.c
index 5a96279..1fe5cc8 100644
--- a/src/log.c
+++ b/src/log.c
@@ -1,4 +1,4 @@
-/* $Id: log.c,v 1.30 2005-07-12 17:39:44 rjkaes Exp $
+/* $Id: log.c,v 1.31 2005-08-15 03:54:31 rjkaes Exp $
*
* Logs the various messages which tinyproxy produces to either a log file or
* the syslog daemon. Not much to it...
@@ -25,15 +25,15 @@
#include "vector.h"
static char *syslog_level[] = {
- NULL,
- NULL,
- "CRITICAL",
- "ERROR",
- "WARNING",
- "NOTICE",
- "INFO",
- "DEBUG",
- "CONNECT"
+ NULL,
+ NULL,
+ "CRITICAL",
+ "ERROR",
+ "WARNING",
+ "NOTICE",
+ "INFO",
+ "DEBUG",
+ "CONNECT"
};
#define TIME_LENGTH 16
@@ -61,10 +61,10 @@ static vector_t log_message_storage;
* Open the log file and store the file descriptor in a global location.
*/
int
-open_log_file(const char* log_file_name)
+open_log_file(const char *log_file_name)
{
- log_file_fd = create_file_safely(log_file_name, FALSE);
- return log_file_fd;
+ log_file_fd = create_file_safely(log_file_name, FALSE);
+ return log_file_fd;
}
/*
@@ -73,7 +73,7 @@ open_log_file(const char* log_file_name)
void
close_log_file(void)
{
- close(log_file_fd);
+ close(log_file_fd);
}
/*
@@ -82,8 +82,8 @@ close_log_file(void)
void
truncate_log_file(void)
{
- lseek(log_file_fd, 0, SEEK_SET);
- ftruncate(log_file_fd, 0);
+ lseek(log_file_fd, 0, SEEK_SET);
+ ftruncate(log_file_fd, 0);
}
/*
@@ -92,7 +92,7 @@ truncate_log_file(void)
void
set_log_level(int level)
{
- log_level = level;
+ log_level = level;
}
/*
@@ -101,92 +101,91 @@ set_log_level(int level)
void
log_message(int level, char *fmt, ...)
{
- va_list args;
- time_t nowtime;
+ va_list args;
+ time_t nowtime;
- char time_string[TIME_LENGTH];
- char str[STRING_LENGTH];
+ char time_string[TIME_LENGTH];
+ char str[STRING_LENGTH];
#ifdef NDEBUG
- /*
- * Figure out if we should write the message or not.
- */
- if (log_level == LOG_CONN) {
- if (level == LOG_INFO)
- return;
- } else if (log_level == LOG_INFO) {
- if (level > LOG_INFO && level != LOG_CONN)
- return;
- } else if (level > log_level)
- return;
+ /*
+ * Figure out if we should write the message or not.
+ */
+ if (log_level == LOG_CONN) {
+ if (level == LOG_INFO)
+ return;
+ } else if (log_level == LOG_INFO) {
+ if (level > LOG_INFO && level != LOG_CONN)
+ return;
+ } else if (level > log_level)
+ return;
#endif
#ifdef HAVE_SYSLOG_H
- if (config.syslog && level == LOG_CONN)
- level = LOG_INFO;
+ if (config.syslog && level == LOG_CONN)
+ level = LOG_INFO;
#endif
- va_start(args, fmt);
+ va_start(args, fmt);
- /*
- * If the config file hasn't been processed, then we need to store
- * the messages for later processing.
- */
- if (!processed_config_file) {
- char* entry_buffer;
+ /*
+ * If the config file hasn't been processed, then we need to store
+ * the messages for later processing.
+ */
+ if (!processed_config_file) {
+ char *entry_buffer;
- if (!log_message_storage) {
- log_message_storage = vector_create();
- if (!log_message_storage)
- return;
- }
+ if (!log_message_storage) {
+ log_message_storage = vector_create();
+ if (!log_message_storage)
+ return;
+ }
- vsnprintf(str, STRING_LENGTH, fmt, args);
+ vsnprintf(str, STRING_LENGTH, fmt, args);
- entry_buffer = safemalloc(strlen(str) + 6);
- if (!entry_buffer)
- return;
-
- sprintf(entry_buffer, "%d %s", level, str);
- vector_append(log_message_storage, entry_buffer,
- strlen(entry_buffer) + 1);
+ entry_buffer = safemalloc(strlen(str) + 6);
+ if (!entry_buffer)
+ return;
- va_end(args);
+ sprintf(entry_buffer, "%d %s", level, str);
+ vector_append(log_message_storage, entry_buffer,
+ strlen(entry_buffer) + 1);
- return;
- }
+ va_end(args);
+ return;
+ }
#ifdef HAVE_SYSLOG_H
- if (config.syslog) {
+ if (config.syslog) {
# ifdef HAVE_VSYSLOG_H
- vsyslog(level, fmt, args);
+ vsyslog(level, fmt, args);
# else
- vsnprintf(str, STRING_LENGTH, fmt, args);
- syslog(level, "%s", str);
+ vsnprintf(str, STRING_LENGTH, fmt, args);
+ syslog(level, "%s", str);
# endif
- } else {
+ } else {
#endif
- nowtime = time(NULL);
- /* Format is month day hour:minute:second (24 time) */
- strftime(time_string, TIME_LENGTH, "%b %d %H:%M:%S",
- localtime(&nowtime));
+ nowtime = time(NULL);
+ /* Format is month day hour:minute:second (24 time) */
+ strftime(time_string, TIME_LENGTH, "%b %d %H:%M:%S",
+ localtime(&nowtime));
- snprintf(str, STRING_LENGTH, "%-9s %s [%ld]: ", syslog_level[level],
- time_string, (long int) getpid());
+ snprintf(str, STRING_LENGTH, "%-9s %s [%ld]: ",
+ syslog_level[level], time_string, (long int)getpid());
- assert(log_file_fd >= 0);
+ assert(log_file_fd >= 0);
- write(log_file_fd, str, strlen(str));
- vsnprintf(str, STRING_LENGTH, fmt, args);
- write(log_file_fd, str, strlen(str));
- write(log_file_fd, "\n", 1);
+ write(log_file_fd, str, strlen(str));
+ vsnprintf(str, STRING_LENGTH, fmt, args);
+ write(log_file_fd, str, strlen(str));
+ write(log_file_fd, "\n", 1);
fsync(log_file_fd);
#ifdef HAVE_SYSLOG_H
- }
+ }
#endif
- va_end(args);
+ va_end(args);
}
/*
@@ -195,32 +194,32 @@ log_message(int level, char *fmt, ...)
void
send_stored_logs(void)
{
- char *string;
- char *ptr;
+ char *string;
+ char *ptr;
- int level;
+ int level;
- int i;
+ int i;
- for (i = 0; i != vector_length(log_message_storage); ++i) {
- string = vector_getentry(log_message_storage, i, NULL);
+ for (i = 0; i != vector_length(log_message_storage); ++i) {
+ string = vector_getentry(log_message_storage, i, NULL);
- ptr = strchr(string, ' ') + 1;
- level = atoi(string);
+ ptr = strchr(string, ' ') + 1;
+ level = atoi(string);
#ifdef NDEBUG
- if (log_level == LOG_CONN && level == LOG_INFO)
- continue;
- else if (log_level == LOG_INFO) {
- if (level > LOG_INFO && level != LOG_CONN)
- continue;
- } else if (level > log_level)
- continue;
+ if (log_level == LOG_CONN && level == LOG_INFO)
+ continue;
+ else if (log_level == LOG_INFO) {
+ if (level > LOG_INFO && level != LOG_CONN)
+ continue;
+ } else if (level > log_level)
+ continue;
#endif
- log_message(level, ptr);
- }
+ log_message(level, ptr);
+ }
- vector_delete(log_message_storage);
- log_message_storage = NULL;
+ vector_delete(log_message_storage);
+ log_message_storage = NULL;
}
diff --git a/src/log.h b/src/log.h
index ae7985e..fdd8ad0 100644
--- a/src/log.h
+++ b/src/log.h
@@ -1,4 +1,4 @@
-/* $Id: log.h,v 1.12 2005-07-12 17:39:44 rjkaes Exp $
+/* $Id: log.h,v 1.13 2005-08-15 03:54:31 rjkaes Exp $
*
* See 'log.c' for a detailed description.
*
@@ -84,7 +84,7 @@
# define LOG_DEBUG 7
#endif
-#define LOG_CONN 8 /* extra to log connections without the INFO stuff */
+#define LOG_CONN 8 /* extra to log connections without the INFO stuff */
/*
* Use this for debugging. The format is specific:
@@ -99,7 +99,7 @@
# define DEBUG2(x, y...) do { } while(0)
#endif
-extern int open_log_file(const char* file);
+extern int open_log_file(const char *file);
extern void close_log_file(void);
extern void truncate_log_file(void);
diff --git a/src/network.c b/src/network.c
index 733a2b6..5a78a42 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1,4 +1,4 @@
-/* $Id: network.c,v 1.4 2004-02-18 20:17:18 rjkaes Exp $
+/* $Id: network.c,v 1.5 2005-08-15 03:54:31 rjkaes Exp $
*
* The functions found here are used for communicating across a
* network. They include both safe reading and writing (which are
@@ -31,33 +31,33 @@
ssize_t
safe_write(int fd, const char *buffer, size_t count)
{
- ssize_t len;
- size_t bytestosend;
+ ssize_t len;
+ size_t bytestosend;
- assert(fd >= 0);
- assert(buffer != NULL);
- assert(count > 0);
+ assert(fd >= 0);
+ assert(buffer != NULL);
+ assert(count > 0);
- bytestosend = count;
+ bytestosend = count;
- while (1) {
- len = send(fd, buffer, bytestosend, MSG_NOSIGNAL);
+ while (1) {
+ len = send(fd, buffer, bytestosend, MSG_NOSIGNAL);
- if (len < 0) {
- if (errno == EINTR)
- continue;
- else
- return -errno;
- }
+ if (len < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ return -errno;
+ }
- if (len == bytestosend)
- break;
+ if (len == bytestosend)
+ break;
- buffer += len;
- bytestosend -= len;
- }
+ buffer += len;
+ bytestosend -= len;
+ }
- return count;
+ return count;
}
/*
@@ -67,13 +67,13 @@ safe_write(int fd, const char *buffer, size_t count)
ssize_t
safe_read(int fd, char *buffer, size_t count)
{
- ssize_t len;
+ ssize_t len;
- do {
- len = read(fd, buffer, count);
- } while (len < 0 && errno == EINTR);
+ do {
+ len = read(fd, buffer, count);
+ } while (len < 0 && errno == EINTR);
- return len;
+ return len;
}
/*
@@ -85,45 +85,45 @@ safe_read(int fd, char *buffer, size_t count)
int
write_message(int fd, const char *fmt, ...)
{
- ssize_t n;
- size_t size = (1024 * 8); /* start with 8 KB and go from there */
- char *buf, *tmpbuf;
- va_list ap;
-
- if ((buf = safemalloc(size)) == NULL)
- return -1;
-
- while (1) {
- va_start(ap, fmt);
- n = vsnprintf(buf, size, fmt, ap);
- va_end(ap);
-
- /* If that worked, break out so we can send the buffer */
- if (n > -1 && n < size)
- break;
-
- /* Else, try again with more space */
- if (n > -1)
- /* precisely what is needed (glibc2.1) */
- size = n + 1;
- else
- /* twice the old size (glibc2.0) */
- size *= 2;
-
- if ((tmpbuf = saferealloc(buf, size)) == NULL) {
- safefree(buf);
- return -1;
- } else
- buf = tmpbuf;
- }
-
- if (safe_write(fd, buf, n) < 0) {
- safefree(buf);
- return -1;
- }
-
- safefree(buf);
- return 0;
+ ssize_t n;
+ size_t size = (1024 * 8); /* start with 8 KB and go from there */
+ char *buf, *tmpbuf;
+ va_list ap;
+
+ if ((buf = safemalloc(size)) == NULL)
+ return -1;
+
+ while (1) {
+ va_start(ap, fmt);
+ n = vsnprintf(buf, size, fmt, ap);
+ va_end(ap);
+
+ /* If that worked, break out so we can send the buffer */
+ if (n > -1 && n < size)
+ break;
+
+ /* Else, try again with more space */
+ if (n > -1)
+ /* precisely what is needed (glibc2.1) */
+ size = n + 1;
+ else
+ /* twice the old size (glibc2.0) */
+ size *= 2;
+
+ if ((tmpbuf = saferealloc(buf, size)) == NULL) {
+ safefree(buf);
+ return -1;
+ } else
+ buf = tmpbuf;
+ }
+
+ if (safe_write(fd, buf, n) < 0) {
+ safefree(buf);
+ return -1;
+ }
+
+ safefree(buf);
+ return 0;
}
/*
@@ -140,132 +140,134 @@ write_message(int fd, const char *fmt, ...)
ssize_t
readline(int fd, char **whole_buffer)
{
- ssize_t whole_buffer_len;
- char buffer[SEGMENT_LEN];
- char *ptr;
-
- ssize_t ret;
- ssize_t diff;
-
- struct read_lines_s {
- char *data;
- size_t len;
- struct read_lines_s *next;
- };
- struct read_lines_s *first_line, *line_ptr;
-
- first_line = safecalloc(sizeof(struct read_lines_s), 1);
- if (!first_line)
- return -ENOMEM;
-
- line_ptr = first_line;
-
- whole_buffer_len = 0;
- for (;;) {
- ret = recv(fd, buffer, SEGMENT_LEN, MSG_PEEK);
- if (ret <= 0)
- goto CLEANUP;
-
- ptr = memchr(buffer, '\n', ret);
- if (ptr)
- diff = ptr - buffer + 1;
- else
- diff = ret;
-
- whole_buffer_len += diff;
-
- /*
- * Don't allow the buffer to grow without bound. If we
- * get to more than MAXIMUM_BUFFER_LENGTH close.
- */
- if (whole_buffer_len > MAXIMUM_BUFFER_LENGTH) {
- ret = -ERANGE;
- goto CLEANUP;
- }
-
- line_ptr->data = safemalloc(diff);
- if (!line_ptr->data) {
- ret = -ENOMEM;
- goto CLEANUP;
- }
-
- recv(fd, line_ptr->data, diff, 0);
- line_ptr->len = diff;
-
- if (ptr) {
- line_ptr->next = NULL;
- break;
- }
-
- line_ptr->next = safecalloc(sizeof(struct read_lines_s), 1);
- if (!line_ptr->next) {
- ret = -ENOMEM;
- goto CLEANUP;
- }
- line_ptr = line_ptr->next;
- }
-
- *whole_buffer = safemalloc(whole_buffer_len + 1);
- if (!*whole_buffer) {
- ret = -ENOMEM;
- goto CLEANUP;
- }
-
- *(*whole_buffer + whole_buffer_len) = '\0';
-
- whole_buffer_len = 0;
- line_ptr = first_line;
- while (line_ptr) {
- memcpy(*whole_buffer + whole_buffer_len, line_ptr->data,
- line_ptr->len);
- whole_buffer_len += line_ptr->len;
-
- line_ptr = line_ptr->next;
- }
-
- ret = whole_buffer_len;
+ ssize_t whole_buffer_len;
+ char buffer[SEGMENT_LEN];
+ char *ptr;
+
+ ssize_t ret;
+ ssize_t diff;
+
+ struct read_lines_s {
+ char *data;
+ size_t len;
+ struct read_lines_s *next;
+ };
+ struct read_lines_s *first_line, *line_ptr;
+
+ first_line = safecalloc(sizeof(struct read_lines_s), 1);
+ if (!first_line)
+ return -ENOMEM;
+
+ line_ptr = first_line;
+
+ whole_buffer_len = 0;
+ for (;;) {
+ ret = recv(fd, buffer, SEGMENT_LEN, MSG_PEEK);
+ if (ret <= 0)
+ goto CLEANUP;
+
+ ptr = memchr(buffer, '\n', ret);
+ if (ptr)
+ diff = ptr - buffer + 1;
+ else
+ diff = ret;
+
+ whole_buffer_len += diff;
+
+ /*
+ * Don't allow the buffer to grow without bound. If we
+ * get to more than MAXIMUM_BUFFER_LENGTH close.
+ */
+ if (whole_buffer_len > MAXIMUM_BUFFER_LENGTH) {
+ ret = -ERANGE;
+ goto CLEANUP;
+ }
+
+ line_ptr->data = safemalloc(diff);
+ if (!line_ptr->data) {
+ ret = -ENOMEM;
+ goto CLEANUP;
+ }
+
+ recv(fd, line_ptr->data, diff, 0);
+ line_ptr->len = diff;
+
+ if (ptr) {
+ line_ptr->next = NULL;
+ break;
+ }
+
+ line_ptr->next = safecalloc(sizeof(struct read_lines_s), 1);
+ if (!line_ptr->next) {
+ ret = -ENOMEM;
+ goto CLEANUP;
+ }
+ line_ptr = line_ptr->next;
+ }
+
+ *whole_buffer = safemalloc(whole_buffer_len + 1);
+ if (!*whole_buffer) {
+ ret = -ENOMEM;
+ goto CLEANUP;
+ }
+
+ *(*whole_buffer + whole_buffer_len) = '\0';
+
+ whole_buffer_len = 0;
+ line_ptr = first_line;
+ while (line_ptr) {
+ memcpy(*whole_buffer + whole_buffer_len, line_ptr->data,
+ line_ptr->len);
+ whole_buffer_len += line_ptr->len;
+
+ line_ptr = line_ptr->next;
+ }
+
+ ret = whole_buffer_len;
CLEANUP:
- do {
- line_ptr = first_line->next;
- if (first_line->data)
- safefree(first_line->data);
- safefree(first_line);
- first_line = line_ptr;
- } while (first_line);
-
- return ret;
+ do {
+ line_ptr = first_line->next;
+ if (first_line->data)
+ safefree(first_line->data);
+ safefree(first_line);
+ first_line = line_ptr;
+ } while (first_line);
+
+ return ret;
}
/*
* Convert the network address into either a dotted-decimal or an IPv6
* hex string.
*/
-char*
-get_ip_string(struct sockaddr* sa, char* buf, size_t buflen)
+char *
+get_ip_string(struct sockaddr *sa, char *buf, size_t buflen)
{
- assert(sa != NULL);
- assert(buf != NULL);
- assert(buflen != 0);
- buf[0] = '\0'; /* start with an empty string */
-
- switch (sa->sa_family) {
- case AF_INET: {
- struct sockaddr_in *sa_in = (struct sockaddr_in *)sa;
- inet_ntop(AF_INET, &sa_in->sin_addr, buf, buflen);
- break;
- }
- case AF_INET6: {
- struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)sa;
- inet_ntop(AF_INET6, &sa_in6->sin6_addr, buf, buflen);
- break;
- }
- default:
- /* no valid family */
- return NULL;
- }
-
- return buf;
+ assert(sa != NULL);
+ assert(buf != NULL);
+ assert(buflen != 0);
+ buf[0] = '\0'; /* start with an empty string */
+
+ switch (sa->sa_family) {
+ case AF_INET:{
+ struct sockaddr_in *sa_in = (struct sockaddr_in *)sa;
+
+ inet_ntop(AF_INET, &sa_in->sin_addr, buf, buflen);
+ break;
+ }
+ case AF_INET6:{
+ struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)sa;
+
+ inet_ntop(AF_INET6, &sa_in6->sin6_addr, buf, buflen);
+ break;
+ }
+ default:
+ /* no valid family */
+ return NULL;
+ }
+
+ return buf;
}
/*
@@ -276,41 +278,41 @@ get_ip_string(struct sockaddr* sa, char* buf, size_t buflen)
* Returns the same as inet_pton().
*/
int
-full_inet_pton(const char* ip, void* dst)
+full_inet_pton(const char *ip, void *dst)
{
- char buf[24], tmp[24]; /* IPv4->IPv6 = ::FFFF:xxx.xxx.xxx.xxx\0 */
- int n;
-
- assert(ip != NULL && strlen(ip) != 0);
- assert(dst != NULL);
-
- /*
- * Check if the string is an IPv4 numeric address. We use the
- * older inet_aton() call since it handles more IPv4 numeric
- * address formats.
- */
- n = inet_aton(ip, (struct in_addr*)dst);
- if (n == 0) {
- /*
- * Simple case: "ip" wasn't an IPv4 numeric address, so
- * try doing the conversion as an IPv6 address. This
- * will either succeed or fail, but we can't do any
- * more processing anyway.
- */
- return inet_pton(AF_INET6, ip, dst);
- }
-
- /*
- * "ip" was an IPv4 address, so we need to convert it to
- * an IPv4-mapped IPv6 address and do the conversion
- * again to get the IPv6 network structure.
- *
- * We convert the IPv4 binary address back into the
- * standard dotted-decimal format using inet_ntop()
- * so we can be sure that inet_pton will accept the
- * full string.
- */
- snprintf(buf, sizeof(buf), "::ffff:%s",
- inet_ntop(AF_INET, dst, tmp, sizeof(tmp)));
- return inet_pton(AF_INET6, buf, dst);
+ char buf[24], tmp[24]; /* IPv4->IPv6 = ::FFFF:xxx.xxx.xxx.xxx\0 */
+ int n;
+
+ assert(ip != NULL && strlen(ip) != 0);
+ assert(dst != NULL);
+
+ /*
+ * Check if the string is an IPv4 numeric address. We use the
+ * older inet_aton() call since it handles more IPv4 numeric
+ * address formats.
+ */
+ n = inet_aton(ip, (struct in_addr *)dst);
+ if (n == 0) {
+ /*
+ * Simple case: "ip" wasn't an IPv4 numeric address, so
+ * try doing the conversion as an IPv6 address. This
+ * will either succeed or fail, but we can't do any
+ * more processing anyway.
+ */
+ return inet_pton(AF_INET6, ip, dst);
+ }
+
+ /*
+ * "ip" was an IPv4 address, so we need to convert it to
+ * an IPv4-mapped IPv6 address and do the conversion
+ * again to get the IPv6 network structure.
+ *
+ * We convert the IPv4 binary address back into the
+ * standard dotted-decimal format using inet_ntop()
+ * so we can be sure that inet_pton will accept the
+ * full string.
+ */
+ snprintf(buf, sizeof(buf), "::ffff:%s",
+ inet_ntop(AF_INET, dst, tmp, sizeof(tmp)));
+ return inet_pton(AF_INET6, buf, dst);
}
diff --git a/src/network.h b/src/network.h
index 68b5381..a1d44bd 100644
--- a/src/network.h
+++ b/src/network.h
@@ -1,4 +1,4 @@
-/* $Id: network.h,v 1.2 2004-02-18 20:17:18 rjkaes Exp $
+/* $Id: network.h,v 1.3 2005-08-15 03:54:31 rjkaes Exp $
*
* See 'network.c' for a detailed description.
*
@@ -24,7 +24,7 @@ extern ssize_t safe_read(int fd, char *buffer, size_t count);
extern int write_message(int fd, const char *fmt, ...);
extern ssize_t readline(int fd, char **whole_buffer);
-extern char* get_ip_string(struct sockaddr* sa, char* buf, size_t len);
-extern int full_inet_pton(const char* ip, void* dst);
+extern char *get_ip_string(struct sockaddr *sa, char *buf, size_t len);
+extern int full_inet_pton(const char *ip, void *dst);
#endif
diff --git a/src/reqs.c b/src/reqs.c
index 5ff225b..e5e4061 100644
--- a/src/reqs.c
+++ b/src/reqs.c
@@ -1,4 +1,4 @@
-/* $Id: reqs.c,v 1.119 2005-07-12 17:39:44 rjkaes Exp $
+/* $Id: reqs.c,v 1.120 2005-08-15 03:54:31 rjkaes Exp $
*
* This is where all the work in tinyproxy is actually done. Incoming
* connections have a new child created for them. The child then
@@ -78,13 +78,13 @@ static vector_t ports_allowed_by_connect = NULL;
* This structure holds the information pulled from a URL request.
*/
struct request_s {
- char *method;
- char *protocol;
+ char *method;
+ char *protocol;
- char *host;
- uint16_t port;
+ char *host;
+ uint16_t port;
- char *path;
+ char *path;
};
/*
@@ -94,16 +94,18 @@ struct request_s {
void
add_connect_port_allowed(int port)
{
- if (!ports_allowed_by_connect) {
- ports_allowed_by_connect = vector_create();
- if (!ports_allowed_by_connect) {
- log_message(LOG_WARNING, "Could not create a list of allowed CONNECT ports");
- return;
- }
- }
-
- log_message(LOG_INFO, "Adding Port [%d] to the list allowed by CONNECT", port);
- vector_append(ports_allowed_by_connect, (void **)&port, sizeof(port));
+ if (!ports_allowed_by_connect) {
+ ports_allowed_by_connect = vector_create();
+ if (!ports_allowed_by_connect) {
+ log_message(LOG_WARNING,
+ "Could not create a list of allowed CONNECT ports");
+ return;
+ }
+ }
+
+ log_message(LOG_INFO, "Adding Port [%d] to the list allowed by CONNECT",
+ port);
+ vector_append(ports_allowed_by_connect, (void **)&port, sizeof(port));
}
/*
@@ -115,23 +117,23 @@ add_connect_port_allowed(int port)
static int
check_allowed_connect_ports(int port)
{
- ssize_t i;
- int *data;
+ ssize_t i;
+ int *data;
/*
* A port list is REQUIRED for a CONNECT request to function
* properly. This closes a potential security hole.
*/
- if (!ports_allowed_by_connect)
- return 0;
+ if (!ports_allowed_by_connect)
+ return 0;
- for (i = 0; i != vector_length(ports_allowed_by_connect); ++i) {
- data = vector_getentry(ports_allowed_by_connect, i, NULL);
+ for (i = 0; i != vector_length(ports_allowed_by_connect); ++i) {
+ data = vector_getentry(ports_allowed_by_connect, i, NULL);
if (data && *data == port)
- return 1;
- }
+ return 1;
+ }
- return 0;
+ return 0;
}
/*
@@ -142,35 +144,35 @@ check_allowed_connect_ports(int port)
static int
read_request_line(struct conn_s *connptr)
{
- ssize_t len;
+ ssize_t len;
retry:
- len = readline(connptr->client_fd, &connptr->request_line);
- if (len <= 0) {
- log_message(LOG_ERR,
- "read_request_line: Client (file descriptor: %d) closed socket before read.",
- connptr->client_fd);
-
- return -1;
- }
-
- /*
- * Strip the new line and carriage return from the string.
- */
- if (chomp(connptr->request_line, len) == len) {
- /*
- * If the number of characters removed is the same as the
- * length then it was a blank line. Free the buffer and
- * try again (since we're looking for a request line.)
- */
- safefree(connptr->request_line);
- goto retry;
- }
-
- log_message(LOG_CONN, "Request (file descriptor %d): %s",
- connptr->client_fd, connptr->request_line);
-
- return 0;
+ len = readline(connptr->client_fd, &connptr->request_line);
+ if (len <= 0) {
+ log_message(LOG_ERR,
+ "read_request_line: Client (file descriptor: %d) closed socket before read.",
+ connptr->client_fd);
+
+ return -1;
+ }
+
+ /*
+ * Strip the new line and carriage return from the string.
+ */
+ if (chomp(connptr->request_line, len) == len) {
+ /*
+ * If the number of characters removed is the same as the
+ * length then it was a blank line. Free the buffer and
+ * try again (since we're looking for a request line.)
+ */
+ safefree(connptr->request_line);
+ goto retry;
+ }
+
+ log_message(LOG_CONN, "Request (file descriptor %d): %s",
+ connptr->client_fd, connptr->request_line);
+
+ return 0;
}
/*
@@ -179,18 +181,18 @@ read_request_line(struct conn_s *connptr)
static void
free_request_struct(struct request_s *request)
{
- if (!request)
- return;
+ if (!request)
+ return;
- safefree(request->method);
- safefree(request->protocol);
+ safefree(request->method);
+ safefree(request->protocol);
- if (request->host)
- safefree(request->host);
- if (request->path)
- safefree(request->path);
+ if (request->host)
+ safefree(request->host);
+ if (request->path)
+ safefree(request->path);
- safefree(request);
+ safefree(request);
}
/*
@@ -198,9 +200,9 @@ free_request_struct(struct request_s *request)
* it off.
*/
static void
-strip_username_password(char* host)
+strip_username_password(char *host)
{
- char *p;
+ char *p;
assert(host);
assert(strlen(host) > 0);
@@ -213,7 +215,7 @@ strip_username_password(char* host)
* until the NUL to the beginning of the host buffer.
*/
p++;
- while (*p)
+ while (*p)
*host++ = *p++;
*host = '\0';
}
@@ -223,19 +225,19 @@ strip_username_password(char* host)
* it off and set proper port variable i.e. for www.host.com:8001
*/
static int
-strip_return_port(char* host)
+strip_return_port(char *host)
{
- char *ptr1;
- int port;
+ char *ptr1;
+ int port;
- ptr1 = strchr(host, ':');
- if (ptr1 == NULL)
- return 0;
+ ptr1 = strchr(host, ':');
+ if (ptr1 == NULL)
+ return 0;
- *ptr1++ = '\0';
- if (sscanf(ptr1, "%d", &port) != 1) /* one conversion required */
- return 0;
- return port;
+ *ptr1++ = '\0';
+ if (sscanf(ptr1, "%d", &port) != 1) /* one conversion required */
+ return 0;
+ return port;
}
/*
@@ -245,42 +247,42 @@ strip_return_port(char* host)
static int
extract_http_url(const char *url, struct request_s *request)
{
- char *p;
- int len;
- int port;
-
- /* Split the URL on the slash to separate host from path */
- p = strchr(url, '/');
- if (p != NULL) {
- len = p - url;
- request->host = safemalloc(len + 1);
- memcpy(request->host, url, len);
- request->host[len] = '\0';
- request->path = safestrdup(p);
- } else {
- request->host = safestrdup(url);
- request->path = safestrdup("/");
- }
-
- if (!request->host || !request->path)
- goto ERROR_EXIT;
-
- /* Remove the username/password if they're present */
- strip_username_password(request->host);
-
- /* Find a proper port in www.site.com:8001 URLs */
- port = strip_return_port(request->host);
- request->port = (port != 0) ? port : HTTP_PORT;
-
- return 0;
-
- ERROR_EXIT:
- if (request->host)
- safefree(request->host);
- if (request->path)
- safefree(request->path);
-
- return -1;
+ char *p;
+ int len;
+ int port;
+
+ /* Split the URL on the slash to separate host from path */
+ p = strchr(url, '/');
+ if (p != NULL) {
+ len = p - url;
+ request->host = safemalloc(len + 1);
+ memcpy(request->host, url, len);
+ request->host[len] = '\0';
+ request->path = safestrdup(p);
+ } else {
+ request->host = safestrdup(url);
+ request->path = safestrdup("/");
+ }
+
+ if (!request->host || !request->path)
+ goto ERROR_EXIT;
+
+ /* Remove the username/password if they're present */
+ strip_username_password(request->host);
+
+ /* Find a proper port in www.site.com:8001 URLs */
+ port = strip_return_port(request->host);
+ request->port = (port != 0) ? port : HTTP_PORT;
+
+ return 0;
+
+ ERROR_EXIT:
+ if (request->host)
+ safefree(request->host);
+ if (request->path)
+ safefree(request->path);
+
+ return -1;
}
/*
@@ -289,24 +291,24 @@ extract_http_url(const char *url, struct request_s *request)
static int
extract_ssl_url(const char *url, struct request_s *request)
{
- request->host = safemalloc(strlen(url) + 1);
- if (!request->host)
- return -1;
-
- if (sscanf(url, "%[^:]:%hu", request->host, &request->port) == 2) ;
- else if (sscanf(url, "%s", request->host) == 1)
- request->port = HTTP_PORT_SSL;
- else {
- log_message(LOG_ERR, "extract_ssl_url: Can't parse URL.");
-
- safefree(request->host);
- return -1;
- }
+ request->host = safemalloc(strlen(url) + 1);
+ if (!request->host)
+ return -1;
+
+ if (sscanf(url, "%[^:]:%hu", request->host, &request->port) == 2) ;
+ else if (sscanf(url, "%s", request->host) == 1)
+ request->port = HTTP_PORT_SSL;
+ else {
+ log_message(LOG_ERR, "extract_ssl_url: Can't parse URL.");
+
+ safefree(request->host);
+ return -1;
+ }
- /* Remove the username/password if they're present */
- strip_username_password(request->host);
+ /* Remove the username/password if they're present */
+ strip_username_password(request->host);
- return 0;
+ return 0;
}
#ifdef TRANSPARENT_PROXY
@@ -316,21 +318,21 @@ extract_ssl_url(const char *url, struct request_s *request)
static int
build_url(char **url, const char *host, int port, const char *path)
{
- int len;
+ int len;
- assert(url != NULL);
- assert(host != NULL);
- assert(port > 0 && port < 32768);
- assert(path != NULL);
+ assert(url != NULL);
+ assert(host != NULL);
+ assert(port > 0 && port < 32768);
+ assert(path != NULL);
- len = strlen(host) + strlen(path) + 14;
- *url = safemalloc(len);
- if (*url == NULL)
- return -1;
+ len = strlen(host) + strlen(path) + 14;
+ *url = safemalloc(len);
+ if (*url == NULL)
+ return -1;
- return snprintf(*url, len, "http://%s:%d%s", host, port, path);
+ return snprintf(*url, len, "http://%s:%d%s", host, port, path);
}
-#endif /* TRANSPARENT_PROXY */
+#endif /* TRANSPARENT_PROXY */
#ifdef UPSTREAM_SUPPORT
/*
@@ -339,99 +341,107 @@ build_url(char **url, const char *host, int port, const char *path)
void
upstream_add(const char *host, int port, const char *domain)
{
- char *ptr;
- struct upstream *up = safemalloc(sizeof (struct upstream));
-
- if (!up) {
- log_message(LOG_ERR, "Unable to allocate memory in upstream_add()");
- return;
- }
-
- up->host = up->domain = NULL;
- up->ip = up->mask = 0;
-
- if (domain == NULL) {
- if (!host || host[0] == '\0' || port < 1) {
- log_message(LOG_WARNING, "Nonsense upstream rule: invalid host or port");
- goto upstream_cleanup;
- }
-
- up->host = safestrdup(host);
- up->port = port;
-
- log_message(LOG_INFO, "Added upstream %s:%d for [default]", host, port);
- } else if (host == NULL) {
- if (!domain || domain[0] == '\0') {
- log_message(LOG_WARNING, "Nonsense no-upstream rule: empty domain");
- goto upstream_cleanup;
- }
-
- ptr = strchr(domain, '/');
- if (ptr) {
- struct in_addr addrstruct;
-
- *ptr = '\0';
- if (inet_aton(domain, &addrstruct) != 0) {
- up->ip = ntohl(addrstruct.s_addr);
- *ptr++ = '/';
-
- if (strchr(ptr, '.')) {
- if (inet_aton(ptr, &addrstruct) != 0)
- up->mask = ntohl(addrstruct.s_addr);
- } else {
- up->mask = ~((1 << (32 - atoi(ptr))) - 1);
- }
- }
- } else {
- up->domain = safestrdup(domain);
- }
-
- log_message(LOG_INFO, "Added no-upstream for %s", domain);
- } else {
- if (!host || host[0] == '\0' || port < 1 || !domain || domain == '\0') {
- log_message(LOG_WARNING, "Nonsense upstream rule: invalid parameters");
- goto upstream_cleanup;
- }
-
- up->host = safestrdup(host);
- up->port = port;
- up->domain = safestrdup(domain);
-
- log_message(LOG_INFO, "Added upstream %s:%d for %s",
- host, port, domain);
- }
-
- if (!up->domain && !up->ip) { /* always add default to end */
- struct upstream *tmp = config.upstream_list;
-
- while (tmp) {
- if (!tmp->domain && !tmp->ip) {
- log_message(LOG_WARNING,
- "Duplicate default upstream");
- goto upstream_cleanup;
- }
-
- if (!tmp->next) {
- up->next = NULL;
- tmp->next = up;
- return;
- }
-
- tmp = tmp->next;
- }
- }
-
- up->next = config.upstream_list;
- config.upstream_list = up;
-
- return;
-
-upstream_cleanup:
- safefree(up->host);
- safefree(up->domain);
- safefree(up);
-
- return;
+ char *ptr;
+ struct upstream *up = safemalloc(sizeof(struct upstream));
+
+ if (!up) {
+ log_message(LOG_ERR,
+ "Unable to allocate memory in upstream_add()");
+ return;
+ }
+
+ up->host = up->domain = NULL;
+ up->ip = up->mask = 0;
+
+ if (domain == NULL) {
+ if (!host || host[0] == '\0' || port < 1) {
+ log_message(LOG_WARNING,
+ "Nonsense upstream rule: invalid host or port");
+ goto upstream_cleanup;
+ }
+
+ up->host = safestrdup(host);
+ up->port = port;
+
+ log_message(LOG_INFO, "Added upstream %s:%d for [default]",
+ host, port);
+ } else if (host == NULL) {
+ if (!domain || domain[0] == '\0') {
+ log_message(LOG_WARNING,
+ "Nonsense no-upstream rule: empty domain");
+ goto upstream_cleanup;
+ }
+
+ ptr = strchr(domain, '/');
+ if (ptr) {
+ struct in_addr addrstruct;
+
+ *ptr = '\0';
+ if (inet_aton(domain, &addrstruct) != 0) {
+ up->ip = ntohl(addrstruct.s_addr);
+ *ptr++ = '/';
+
+ if (strchr(ptr, '.')) {
+ if (inet_aton(ptr, &addrstruct) != 0)
+ up->mask =
+ ntohl(addrstruct.s_addr);
+ } else {
+ up->mask =
+ ~((1 << (32 - atoi(ptr))) - 1);
+ }
+ }
+ } else {
+ up->domain = safestrdup(domain);
+ }
+
+ log_message(LOG_INFO, "Added no-upstream for %s", domain);
+ } else {
+ if (!host || host[0] == '\0' || port < 1 || !domain
+ || domain == '\0') {
+ log_message(LOG_WARNING,
+ "Nonsense upstream rule: invalid parameters");
+ goto upstream_cleanup;
+ }
+
+ up->host = safestrdup(host);
+ up->port = port;
+ up->domain = safestrdup(domain);
+
+ log_message(LOG_INFO, "Added upstream %s:%d for %s",
+ host, port, domain);
+ }
+
+ if (!up->domain && !up->ip) { /* always add default to end */
+ struct upstream *tmp = config.upstream_list;
+
+ while (tmp) {
+ if (!tmp->domain && !tmp->ip) {
+ log_message(LOG_WARNING,
+ "Duplicate default upstream");
+ goto upstream_cleanup;
+ }
+
+ if (!tmp->next) {
+ up->next = NULL;
+ tmp->next = up;
+ return;
+ }
+
+ tmp = tmp->next;
+ }
+ }
+
+ up->next = config.upstream_list;
+ config.upstream_list = up;
+
+ return;
+
+ upstream_cleanup:
+ safefree(up->host);
+ safefree(up->domain);
+ safefree(up);
+
+ return;
}
/*
@@ -440,50 +450,50 @@ upstream_cleanup:
static struct upstream *
upstream_get(char *host)
{
- struct upstream *up = config.upstream_list;
+ struct upstream *up = config.upstream_list;
- in_addr_t my_ip = INADDR_NONE;
+ in_addr_t my_ip = INADDR_NONE;
- while (up) {
- if (up->domain) {
- if (strcasecmp(host, up->domain) == 0)
- break; /* exact match */
+ while (up) {
+ if (up->domain) {
+ if (strcasecmp(host, up->domain) == 0)
+ break; /* exact match */
- if (up->domain[0] == '.') {
- char *dot = strchr(host, '.');
+ if (up->domain[0] == '.') {
+ char *dot = strchr(host, '.');
- if (!dot && !up->domain[1])
- break; /* local host matches "." */
+ if (!dot && !up->domain[1])
+ break; /* local host matches "." */
- while (dot && strcasecmp(dot, up->domain))
- dot = strchr(dot+1, '.');
+ while (dot && strcasecmp(dot, up->domain))
+ dot = strchr(dot + 1, '.');
- if (dot)
- break; /* subdomain match */
- }
- } else if (up->ip) {
- if (my_ip == INADDR_NONE)
- my_ip = ntohl(inet_addr(host));
+ if (dot)
+ break; /* subdomain match */
+ }
+ } else if (up->ip) {
+ if (my_ip == INADDR_NONE)
+ my_ip = ntohl(inet_addr(host));
- if ((my_ip & up->mask) == up->ip)
- break;
- } else {
- break; /* No domain or IP, default upstream */
- }
+ if ((my_ip & up->mask) == up->ip)
+ break;
+ } else {
+ break; /* No domain or IP, default upstream */
+ }
- up = up->next;
- }
+ up = up->next;
+ }
- if (up && (!up->host || !up->port))
- up = NULL;
+ if (up && (!up->host || !up->port))
+ up = NULL;
- if (up)
- log_message(LOG_INFO, "Found proxy %s:%d for %s",
- up->host, up->port, host);
- else
- log_message(LOG_INFO, "No proxy for %s", host);
+ if (up)
+ log_message(LOG_INFO, "Found proxy %s:%d for %s",
+ up->host, up->port, host);
+ else
+ log_message(LOG_INFO, "No proxy for %s", host);
- return up;
+ return up;
}
#endif
@@ -494,40 +504,47 @@ upstream_get(char *host)
void
reversepath_add(const char *path, const char *url)
{
- struct reversepath *reverse;
+ struct reversepath *reverse;
- if (url == NULL) {
- log_message(LOG_WARNING, "Illegal reverse proxy rule: missing url");
- return;
- }
+ if (url == NULL) {
+ log_message(LOG_WARNING,
+ "Illegal reverse proxy rule: missing url");
+ return;
+ }
- if (!strstr(url, "://")) {
- log_message(LOG_WARNING,
- "Skipping reverse proxy rule: '%s' is not a valid url", url);
- return;
- }
+ if (!strstr(url, "://")) {
+ log_message(LOG_WARNING,
+ "Skipping reverse proxy rule: '%s' is not a valid url",
+ url);
+ return;
+ }
- if (path && *path != '/') {
- log_message(LOG_WARNING,
- "Skipping reverse proxy rule: path '%s' doesn't start with a /", path);
- return;
- }
+ if (path && *path != '/') {
+ log_message(LOG_WARNING,
+ "Skipping reverse proxy rule: path '%s' doesn't start with a /",
+ path);
+ return;
+ }
- if (!(reverse = safemalloc(sizeof (struct reversepath)))) {
- log_message(LOG_ERR, "Unable to allocate memory in reversepath_add()");
- return;
- }
+ if (!(reverse = safemalloc(sizeof(struct reversepath)))) {
+ log_message(LOG_ERR,
+ "Unable to allocate memory in reversepath_add()");
+ return;
+ }
- if (!path) reverse->path = safestrdup("/");
- else reverse->path = safestrdup(path);
+ if (!path)
+ reverse->path = safestrdup("/");
+ else
+ reverse->path = safestrdup(path);
- reverse->url = safestrdup(url);
+ reverse->url = safestrdup(url);
- reverse->next = config.reversepath_list;
- config.reversepath_list = reverse;
+ reverse->next = config.reversepath_list;
+ config.reversepath_list = reverse;
- log_message(LOG_INFO,
- "Added reverse proxy rule: %s -> %s", reverse->path, reverse->url);
+ log_message(LOG_INFO,
+ "Added reverse proxy rule: %s -> %s", reverse->path,
+ reverse->url);
}
/*
@@ -536,16 +553,16 @@ reversepath_add(const char *path, const char *url)
static struct reversepath *
reversepath_get(char *url)
{
- struct reversepath *reverse = config.reversepath_list;
+ struct reversepath *reverse = config.reversepath_list;
- while (reverse) {
- if (strstr(url, reverse->path) == url)
- return reverse;
+ while (reverse) {
+ if (strstr(url, reverse->path) == url)
+ return reverse;
- reverse = reverse->next;
- }
+ reverse = reverse->next;
+ }
- return NULL;
+ return NULL;
}
#endif
@@ -555,20 +572,20 @@ reversepath_get(char *url)
static int
establish_http_connection(struct conn_s *connptr, struct request_s *request)
{
- char portbuff[7];
-
- /* Build a port string if it's not a standard port */
- if (request->port != HTTP_PORT && request->port != HTTP_PORT_SSL)
- snprintf(portbuff, 7, ":%u", request->port);
- else
- portbuff[0] = '\0';
-
- return write_message(connptr->server_fd,
- "%s %s HTTP/1.0\r\n" \
- "Host: %s%s\r\n" \
- "Connection: close\r\n",
- request->method, request->path,
- request->host, portbuff);
+ char portbuff[7];
+
+ /* Build a port string if it's not a standard port */
+ if (request->port != HTTP_PORT && request->port != HTTP_PORT_SSL)
+ snprintf(portbuff, 7, ":%u", request->port);
+ else
+ portbuff[0] = '\0';
+
+ return write_message(connptr->server_fd,
+ "%s %s HTTP/1.0\r\n"
+ "Host: %s%s\r\n"
+ "Connection: close\r\n",
+ request->method, request->path,
+ request->host, portbuff);
}
/*
@@ -584,11 +601,10 @@ establish_http_connection(struct conn_s *connptr, struct request_s *request)
static inline int
send_ssl_response(struct conn_s *connptr)
{
- return write_message(connptr->client_fd,
- "%s\r\n" \
- "%s\r\n" \
- "\r\n",
- SSL_CONNECTION_RESPONSE, PROXY_AGENT);
+ return write_message(connptr->client_fd,
+ "%s\r\n"
+ "%s\r\n"
+ "\r\n", SSL_CONNECTION_RESPONSE, PROXY_AGENT);
}
/*
@@ -598,42 +614,42 @@ send_ssl_response(struct conn_s *connptr)
static struct request_s *
process_request(struct conn_s *connptr, hashmap_t hashofheaders)
{
- char *url;
- struct request_s *request;
+ char *url;
+ struct request_s *request;
#ifdef REVERSE_SUPPORT
- char *rewrite_url = NULL;
- char *cookie = NULL;
- char *cookieval;
- struct reversepath *reverse;
+ char *rewrite_url = NULL;
+ char *cookie = NULL;
+ char *cookieval;
+ struct reversepath *reverse;
#endif
- int ret;
+ int ret;
- size_t request_len;
+ size_t request_len;
- /* NULL out all the fields so frees don't cause segfaults. */
- request = safecalloc(1, sizeof(struct request_s));
- if (!request)
- return NULL;
+ /* NULL out all the fields so frees don't cause segfaults. */
+ request = safecalloc(1, sizeof(struct request_s));
+ if (!request)
+ return NULL;
- request_len = strlen(connptr->request_line) + 1;
+ request_len = strlen(connptr->request_line) + 1;
- request->method = safemalloc(request_len);
- url = safemalloc(request_len);
- request->protocol = safemalloc(request_len);
+ request->method = safemalloc(request_len);
+ url = safemalloc(request_len);
+ request->protocol = safemalloc(request_len);
- if (!request->method || !url || !request->protocol) {
- safefree(url);
- free_request_struct(request);
+ if (!request->method || !url || !request->protocol) {
+ safefree(url);
+ free_request_struct(request);
- return NULL;
- }
+ return NULL;
+ }
- ret = sscanf(connptr->request_line, "%[^ ] %[^ ] %[^ ]",
+ ret = sscanf(connptr->request_line, "%[^ ] %[^ ] %[^ ]",
request->method, url, request->protocol);
if (ret == 2 && !strcasecmp(request->method, "GET")) {
- request->protocol[0] = 0;
+ request->protocol[0] = 0;
/* Indicate that this is a HTTP/0.9 GET request */
connptr->protocol.major = 0;
@@ -654,271 +670,283 @@ process_request(struct conn_s *connptr, hashmap_t hashofheaders)
if (ret != 2)
goto BAD_REQUEST_ERROR;
} else {
- BAD_REQUEST_ERROR:
- log_message(LOG_ERR,
- "process_request: Bad Request on file descriptor %d",
- connptr->client_fd);
- indicate_http_error(connptr, 400, "Bad Request",
- "detail", "Request has an invalid format",
- "url", url,
- NULL);
-
- safefree(url);
- free_request_struct(request);
-
- return NULL;
- }
-
- if (!url) {
- log_message(LOG_ERR,
- "process_request: Null URL on file descriptor %d",
- connptr->client_fd);
- indicate_http_error(connptr, 400, "Bad Request",
- "detail", "Request has an empty URL",
- "url", url,
- NULL);
-
- safefree(url);
- free_request_struct(request);
-
- return NULL;
- }
+ BAD_REQUEST_ERROR:
+ log_message(LOG_ERR,
+ "process_request: Bad Request on file descriptor %d",
+ connptr->client_fd);
+ indicate_http_error(connptr, 400, "Bad Request",
+ "detail", "Request has an invalid format",
+ "url", url, NULL);
+
+ safefree(url);
+ free_request_struct(request);
+
+ return NULL;
+ }
+ if (!url) {
+ log_message(LOG_ERR,
+ "process_request: Null URL on file descriptor %d",
+ connptr->client_fd);
+ indicate_http_error(connptr, 400, "Bad Request",
+ "detail", "Request has an empty URL",
+ "url", url, NULL);
+
+ safefree(url);
+ free_request_struct(request);
+
+ return NULL;
+ }
#ifdef REVERSE_SUPPORT
- /*
- * Reverse proxy URL rewriting.
- */
- if (config.reversepath_list != NULL) {
- /* Reverse requests always start with a slash */
- if (*url == '/') {
- /* First try locating the reverse mapping by request url */
- reverse = reversepath_get(url);
- if (reverse) {
- rewrite_url = safemalloc(strlen(url) +
- strlen(reverse->url) + 1);
- strcpy(rewrite_url, reverse->url);
- strcat(rewrite_url, url + strlen(reverse->path));
- } else if (config.reversemagic &&
- hashmap_entry_by_key(hashofheaders, "cookie",
- (void **)&cookie) > 0) {
-
- /* No match - try the magical tracking cookie next */
- if ((cookieval = strstr(cookie, REVERSE_COOKIE "=")) &&
- (reverse = reversepath_get(cookieval +
- strlen(REVERSE_COOKIE) + 1))) {
-
- rewrite_url = safemalloc(strlen(url) +
- strlen(reverse->url) + 1);
- strcpy(rewrite_url, reverse->url);
- strcat(rewrite_url, url + 1);
-
- log_message(LOG_INFO,
- "Magical tracking cookie says: %s",
- reverse->path);
- }
- }
- }
-
- /* Forward proxy support off and no reverse path match found */
- if (config.reverseonly && !rewrite_url) {
- log_message(LOG_ERR, "Bad request");
- indicate_http_error(connptr, 400, "Bad Request",
- "detail", "Request has an invalid URL",
- "url", url,
- NULL);
-
- safefree(url);
- free_request_struct(request);
-
- return NULL;
- }
-
- log_message(LOG_CONN, "Rewriting URL: %s -> %s",
- url, rewrite_url);
-
- safefree(url);
- url = rewrite_url;
-
- /* Store reverse path so that the magical tracking cookie can be set */
- if (config.reversemagic) connptr->reversepath = safestrdup(reverse->path);
- }
+ /*
+ * Reverse proxy URL rewriting.
+ */
+ if (config.reversepath_list != NULL) {
+ /* Reverse requests always start with a slash */
+ if (*url == '/') {
+ /* First try locating the reverse mapping by request url */
+ reverse = reversepath_get(url);
+ if (reverse) {
+ rewrite_url = safemalloc(strlen(url) +
+ strlen(reverse->url) +
+ 1);
+ strcpy(rewrite_url, reverse->url);
+ strcat(rewrite_url,
+ url + strlen(reverse->path));
+ } else if (config.reversemagic
+ && hashmap_entry_by_key(hashofheaders,
+ "cookie",
+ (void **)&cookie) >
+ 0) {
+
+ /* No match - try the magical tracking cookie next */
+ if ((cookieval =
+ strstr(cookie, REVERSE_COOKIE "="))
+ && (reverse =
+ reversepath_get(cookieval +
+ strlen(REVERSE_COOKIE) +
+ 1))) {
+
+ rewrite_url = safemalloc(strlen(url) +
+ strlen
+ (reverse->
+ url) + 1);
+ strcpy(rewrite_url, reverse->url);
+ strcat(rewrite_url, url + 1);
+
+ log_message(LOG_INFO,
+ "Magical tracking cookie says: %s",
+ reverse->path);
+ }
+ }
+ }
+
+ /* Forward proxy support off and no reverse path match found */
+ if (config.reverseonly && !rewrite_url) {
+ log_message(LOG_ERR, "Bad request");
+ indicate_http_error(connptr, 400, "Bad Request",
+ "detail",
+ "Request has an invalid URL", "url",
+ url, NULL);
+
+ safefree(url);
+ free_request_struct(request);
+
+ return NULL;
+ }
+
+ log_message(LOG_CONN, "Rewriting URL: %s -> %s",
+ url, rewrite_url);
+
+ safefree(url);
+ url = rewrite_url;
+
+ /* Store reverse path so that the magical tracking cookie can be set */
+ if (config.reversemagic)
+ connptr->reversepath = safestrdup(reverse->path);
+ }
#endif
- if (strncasecmp(url, "http://", 7) == 0
- || (UPSTREAM_CONFIGURED() && strncasecmp(url, "ftp://", 6) == 0)) {
- char *skipped_type = strstr(url, "//") + 2;
-
- if (extract_http_url(skipped_type, request) < 0) {
- indicate_http_error(connptr, 400, "Bad Request",
- "detail", "Could not parse URL",
- "url", url,
- NULL);
-
- safefree(url);
- free_request_struct(request);
-
- return NULL;
- }
- } else if (strcmp(request->method, "CONNECT") == 0) {
- if (extract_ssl_url(url, request) < 0) {
- indicate_http_error(connptr, 400, "Bad Request",
- "detail", "Could not parse URL",
- "url", url,
- NULL);
-
- safefree(url);
- free_request_struct(request);
-
- return NULL;
- }
-
- /* Verify that the port in the CONNECT method is allowed */
- if (!check_allowed_connect_ports(request->port)) {
- indicate_http_error(connptr, 403, "Access violation",
- "detail", "The CONNECT method not allowed " \
- "with the port you tried to use.",
- "url", url,
- NULL);
- log_message(LOG_INFO, "Refused CONNECT method on port %d",
- request->port);
-
- safefree(url);
- free_request_struct(request);
-
- return NULL;
- }
-
- connptr->connect_method = TRUE;
- } else {
+ if (strncasecmp(url, "http://", 7) == 0
+ || (UPSTREAM_CONFIGURED() && strncasecmp(url, "ftp://", 6) == 0)) {
+ char *skipped_type = strstr(url, "//") + 2;
+
+ if (extract_http_url(skipped_type, request) < 0) {
+ indicate_http_error(connptr, 400, "Bad Request",
+ "detail", "Could not parse URL",
+ "url", url, NULL);
+
+ safefree(url);
+ free_request_struct(request);
+
+ return NULL;
+ }
+ } else if (strcmp(request->method, "CONNECT") == 0) {
+ if (extract_ssl_url(url, request) < 0) {
+ indicate_http_error(connptr, 400, "Bad Request",
+ "detail", "Could not parse URL",
+ "url", url, NULL);
+
+ safefree(url);
+ free_request_struct(request);
+
+ return NULL;
+ }
+
+ /* Verify that the port in the CONNECT method is allowed */
+ if (!check_allowed_connect_ports(request->port)) {
+ indicate_http_error(connptr, 403, "Access violation",
+ "detail",
+ "The CONNECT method not allowed "
+ "with the port you tried to use.",
+ "url", url, NULL);
+ log_message(LOG_INFO,
+ "Refused CONNECT method on port %d",
+ request->port);
+
+ safefree(url);
+ free_request_struct(request);
+
+ return NULL;
+ }
+
+ connptr->connect_method = TRUE;
+ } else {
#ifdef TRANSPARENT_PROXY
- /*
- * This section of code is used for the transparent proxy
- * option. You will need to configure your firewall to
- * redirect all connections for HTTP traffic to tinyproxy
- * for this to work properly.
- *
- * This code was written by Petr Lampa <lampa@fit.vutbr.cz>
- */
- int length;
- char *data;
- length = hashmap_entry_by_key(hashofheaders, "host", (void **)&data);
- if (length <= 0) {
- struct sockaddr_in dest_addr;
-
- if (getsockname(connptr->client_fd, (struct sockaddr *)&dest_addr, &length) < 0) {
- log_message(LOG_ERR,
- "process_request: cannot get destination IP for %d",
- connptr->client_fd);
- indicate_http_error(connptr, 400, "Bad Request",
- "detail", "Unknown destination",
- "url", url,
- NULL);
- safefree(url);
- free_request_struct(request);
- return NULL;
- }
- request->host = safemalloc(17);
- strcpy(request->host, inet_ntoa(dest_addr.sin_addr));
- request->port = ntohs(dest_addr.sin_port);
- request->path = safemalloc(strlen(url) + 1);
- strcpy(request->path, url);
- safefree(url);
- build_url(&url, request->host, request->port, request->path);
- log_message(LOG_INFO,
- "process_request: trans IP %s %s for %d",
- request->method, url, connptr->client_fd);
- } else {
- request->host = safemalloc(length+1);
- if (sscanf(data, "%[^:]:%hu", request->host, &request->port) != 2) {
- strcpy(request->host, data);
- request->port = HTTP_PORT;
- }
- request->path = safemalloc(strlen(url) + 1);
- strcpy(request->path, url);
- safefree(url);
- build_url(&url, request->host, request->port, request->path);
- log_message(LOG_INFO,
- "process_request: trans Host %s %s for %d",
- request->method, url, connptr->client_fd);
- }
- if (config.ipAddr &&
- strcmp(request->host, config.ipAddr) == 0) {
- log_message(LOG_ERR,
- "process_request: destination IP is localhost %d",
- connptr->client_fd);
- indicate_http_error(connptr, 400, "Bad Request",
- "detail", "You tried to connect to the machine the proxy is running on",
- "url", url,
- NULL);
- safefree(url);
- free_request_struct(request);
- return NULL;
- }
+ /*
+ * This section of code is used for the transparent proxy
+ * option. You will need to configure your firewall to
+ * redirect all connections for HTTP traffic to tinyproxy
+ * for this to work properly.
+ *
+ * This code was written by Petr Lampa <lampa@fit.vutbr.cz>
+ */
+ int length;
+ char *data;
+
+ length =
+ hashmap_entry_by_key(hashofheaders, "host", (void **)&data);
+ if (length <= 0) {
+ struct sockaddr_in dest_addr;
+
+ if (getsockname
+ (connptr->client_fd, (struct sockaddr *)&dest_addr,
+ &length) < 0) {
+ log_message(LOG_ERR,
+ "process_request: cannot get destination IP for %d",
+ connptr->client_fd);
+ indicate_http_error(connptr, 400, "Bad Request",
+ "detail",
+ "Unknown destination",
+ "url", url, NULL);
+ safefree(url);
+ free_request_struct(request);
+ return NULL;
+ }
+ request->host = safemalloc(17);
+ strcpy(request->host, inet_ntoa(dest_addr.sin_addr));
+ request->port = ntohs(dest_addr.sin_port);
+ request->path = safemalloc(strlen(url) + 1);
+ strcpy(request->path, url);
+ safefree(url);
+ build_url(&url, request->host, request->port,
+ request->path);
+ log_message(LOG_INFO,
+ "process_request: trans IP %s %s for %d",
+ request->method, url, connptr->client_fd);
+ } else {
+ request->host = safemalloc(length + 1);
+ if (sscanf
+ (data, "%[^:]:%hu", request->host,
+ &request->port) != 2) {
+ strcpy(request->host, data);
+ request->port = HTTP_PORT;
+ }
+ request->path = safemalloc(strlen(url) + 1);
+ strcpy(request->path, url);
+ safefree(url);
+ build_url(&url, request->host, request->port,
+ request->path);
+ log_message(LOG_INFO,
+ "process_request: trans Host %s %s for %d",
+ request->method, url, connptr->client_fd);
+ }
+ if (config.ipAddr && strcmp(request->host, config.ipAddr) == 0) {
+ log_message(LOG_ERR,
+ "process_request: destination IP is localhost %d",
+ connptr->client_fd);
+ indicate_http_error(connptr, 400, "Bad Request",
+ "detail",
+ "You tried to connect to the machine the proxy is running on",
+ "url", url, NULL);
+ safefree(url);
+ free_request_struct(request);
+ return NULL;
+ }
#else
- log_message(LOG_ERR,
- "process_request: Unknown URL type on file descriptor %d",
- connptr->client_fd);
- indicate_http_error(connptr, 400, "Bad Request",
- "detail", "Unknown URL type",
- "url", url,
- NULL);
-
- safefree(url);
- free_request_struct(request);
-
- return NULL;
+ log_message(LOG_ERR,
+ "process_request: Unknown URL type on file descriptor %d",
+ connptr->client_fd);
+ indicate_http_error(connptr, 400, "Bad Request",
+ "detail", "Unknown URL type",
+ "url", url, NULL);
+
+ safefree(url);
+ free_request_struct(request);
+
+ return NULL;
#endif
- }
+ }
#ifdef FILTER_ENABLE
- /*
- * Filter restricted domains/urls
- */
- if (config.filter) {
- if (config.filter_url)
- ret = filter_url(url);
- else
- ret = filter_domain(request->host);
-
- if (ret) {
- update_stats(STAT_DENIED);
-
- if (config.filter_url)
- log_message(LOG_NOTICE,
- "Proxying refused on filtered url \"%s\"",
- url);
- else
- log_message(LOG_NOTICE,
- "Proxying refused on filtered domain \"%s\"",
- request->host);
-
- indicate_http_error(connptr, 403, "Filtered",
- "detail", "The request you made has been filtered",
- "url", url,
- NULL);
-
- safefree(url);
- free_request_struct(request);
-
- return NULL;
- }
- }
+ /*
+ * Filter restricted domains/urls
+ */
+ if (config.filter) {
+ if (config.filter_url)
+ ret = filter_url(url);
+ else
+ ret = filter_domain(request->host);
+
+ if (ret) {
+ update_stats(STAT_DENIED);
+
+ if (config.filter_url)
+ log_message(LOG_NOTICE,
+ "Proxying refused on filtered url \"%s\"",
+ url);
+ else
+ log_message(LOG_NOTICE,
+ "Proxying refused on filtered domain \"%s\"",
+ request->host);
+
+ indicate_http_error(connptr, 403, "Filtered",
+ "detail",
+ "The request you made has been filtered",
+ "url", url, NULL);
+
+ safefree(url);
+ free_request_struct(request);
+
+ return NULL;
+ }
+ }
#endif
- safefree(url);
+ safefree(url);
- /*
- * Check to see if they're requesting the stat host
- */
- if (config.stathost && strcmp(config.stathost, request->host) == 0) {
- log_message(LOG_NOTICE, "Request for the stathost.");
- connptr->show_stats = TRUE;
+ /*
+ * Check to see if they're requesting the stat host
+ */
+ if (config.stathost && strcmp(config.stathost, request->host) == 0) {
+ log_message(LOG_NOTICE, "Request for the stathost.");
+ connptr->show_stats = TRUE;
- free_request_struct(request);
- return NULL;
- }
+ free_request_struct(request);
+ return NULL;
+ }
- return request;
+ return request;
}
/*
@@ -930,48 +958,48 @@ process_request(struct conn_s *connptr, hashmap_t hashofheaders)
static int
pull_client_data(struct conn_s *connptr, long int length)
{
- char *buffer;
- ssize_t len;
-
- buffer = safemalloc(min(MAXBUFFSIZE, length));
- if (!buffer)
- return -1;
-
- do {
- len = safe_read(connptr->client_fd, buffer,
- min(MAXBUFFSIZE, length));
- if (len <= 0)
- goto ERROR_EXIT;
-
- if (!connptr->error_variables) {
- if (safe_write(connptr->server_fd, buffer, len) < 0)
- goto ERROR_EXIT;
- }
-
- length -= len;
- } while (length > 0);
-
- /*
- * BUG FIX: Internet Explorer will leave two bytes (carriage
- * return and line feed) at the end of a POST message. These
- * need to be eaten for tinyproxy to work correctly.
- */
- socket_nonblocking(connptr->client_fd);
- len = recv(connptr->client_fd, buffer, 2, MSG_PEEK);
- socket_blocking(connptr->client_fd);
-
- if (len < 0 && errno != EAGAIN)
- goto ERROR_EXIT;
-
- if (len == 2 && CHECK_CRLF(buffer, len))
- read(connptr->client_fd, buffer, 2);
-
- safefree(buffer);
- return 0;
-
- ERROR_EXIT:
- safefree(buffer);
- return -1;
+ char *buffer;
+ ssize_t len;
+
+ buffer = safemalloc(min(MAXBUFFSIZE, length));
+ if (!buffer)
+ return -1;
+
+ do {
+ len = safe_read(connptr->client_fd, buffer,
+ min(MAXBUFFSIZE, length));
+ if (len <= 0)
+ goto ERROR_EXIT;
+
+ if (!connptr->error_variables) {
+ if (safe_write(connptr->server_fd, buffer, len) < 0)
+ goto ERROR_EXIT;
+ }
+
+ length -= len;
+ } while (length > 0);
+
+ /*
+ * BUG FIX: Internet Explorer will leave two bytes (carriage
+ * return and line feed) at the end of a POST message. These
+ * need to be eaten for tinyproxy to work correctly.
+ */
+ socket_nonblocking(connptr->client_fd);
+ len = recv(connptr->client_fd, buffer, 2, MSG_PEEK);
+ socket_blocking(connptr->client_fd);
+
+ if (len < 0 && errno != EAGAIN)
+ goto ERROR_EXIT;
+
+ if (len == 2 && CHECK_CRLF(buffer, len))
+ read(connptr->client_fd, buffer, 2);
+
+ safefree(buffer);
+ return 0;
+
+ ERROR_EXIT:
+ safefree(buffer);
+ return -1;
}
#ifdef XTINYPROXY_ENABLE
@@ -984,11 +1012,10 @@ static inline int
add_xtinyproxy_header(struct conn_s *connptr)
{
assert(connptr && connptr->server_fd >= 0);
- return write_message(connptr->server_fd,
- "X-Tinyproxy: %s\r\n",
- connptr->client_ip_addr);
+ return write_message(connptr->server_fd,
+ "X-Tinyproxy: %s\r\n", connptr->client_ip_addr);
}
-#endif /* XTINYPROXY */
+#endif /* XTINYPROXY */
/*
* Take a complete header line and break it apart (into a key and the data.)
@@ -998,23 +1025,23 @@ add_xtinyproxy_header(struct conn_s *connptr)
static inline int
add_header_to_connection(hashmap_t hashofheaders, char *header, size_t len)
{
- char *sep;
+ char *sep;
- /* Get rid of the new line and return at the end */
- len -= chomp(header, len);
+ /* Get rid of the new line and return at the end */
+ len -= chomp(header, len);
- sep = strchr(header, ':');
- if (!sep)
- return -1;
+ sep = strchr(header, ':');
+ if (!sep)
+ return -1;
- /* Blank out colons, spaces, and tabs. */
- while (*sep == ':' || *sep == ' ' || *sep == '\t')
- *sep++ = '\0';
+ /* Blank out colons, spaces, and tabs. */
+ while (*sep == ':' || *sep == ' ' || *sep == '\t')
+ *sep++ = '\0';
- /* Calculate the new length of just the data */
- len -= sep - header - 1;
+ /* Calculate the new length of just the data */
+ len -= sep - header - 1;
- return hashmap_insert(hashofheaders, header, sep, len);
+ return hashmap_insert(hashofheaders, header, sep, len);
}
/*
@@ -1023,54 +1050,55 @@ add_header_to_connection(hashmap_t hashofheaders, char *header, size_t len)
static int
get_all_headers(int fd, hashmap_t hashofheaders)
{
- char *header;
- ssize_t len;
- unsigned int double_cgi = FALSE; /* boolean */
-
- assert(fd >= 0);
- assert(hashofheaders != NULL);
-
- for (;;) {
- if ((len = readline(fd, &header)) <= 0) {
- safefree(header);
- return -1;
- }
-
- /*
- * If we received just a CR LF on a line, the headers are
- * finished.
- */
- if (CHECK_CRLF(header, len)) {
- safefree(header);
- return 0;
- }
-
- /*
- * BUG FIX: The following code detects a "Double CGI"
- * situation so that we can handle the nonconforming system.
- * This problem was found when accessing cgi.ebay.com, and it
- * turns out to be a wider spread problem as well.
- *
- * If "Double CGI" is in effect, duplicate headers are
- * ignored.
- *
- * FIXME: Might need to change this to a more robust check.
- */
- if (strncasecmp(header, "HTTP/", 5) == 0) {
- double_cgi = TRUE;
-
- safefree(header);
- continue;
- }
-
- if (!double_cgi
- && add_header_to_connection(hashofheaders, header, len) < 0) {
- safefree(header);
- return -1;
- }
-
- safefree(header);
- }
+ char *header;
+ ssize_t len;
+ unsigned int double_cgi = FALSE; /* boolean */
+
+ assert(fd >= 0);
+ assert(hashofheaders != NULL);
+
+ for (;;) {
+ if ((len = readline(fd, &header)) <= 0) {
+ safefree(header);
+ return -1;
+ }
+
+ /*
+ * If we received just a CR LF on a line, the headers are
+ * finished.
+ */
+ if (CHECK_CRLF(header, len)) {
+ safefree(header);
+ return 0;
+ }
+
+ /*
+ * BUG FIX: The following code detects a "Double CGI"
+ * situation so that we can handle the nonconforming system.
+ * This problem was found when accessing cgi.ebay.com, and it
+ * turns out to be a wider spread problem as well.
+ *
+ * If "Double CGI" is in effect, duplicate headers are
+ * ignored.
+ *
+ * FIXME: Might need to change this to a more robust check.
+ */
+ if (strncasecmp(header, "HTTP/", 5) == 0) {
+ double_cgi = TRUE;
+
+ safefree(header);
+ continue;
+ }
+
+ if (!double_cgi
+ && add_header_to_connection(hashofheaders, header,
+ len) < 0) {
+ safefree(header);
+ return -1;
+ }
+
+ safefree(header);
+ }
}
/*
@@ -1080,49 +1108,51 @@ get_all_headers(int fd, hashmap_t hashofheaders)
static int
remove_connection_headers(hashmap_t hashofheaders)
{
- static char* headers[] = {
- "connection",
- "proxy-connection"
- };
-
- char *data;
- char* ptr;
- ssize_t len;
- int i;
-
- for (i = 0; i != (sizeof(headers) / sizeof(char *)); ++i) {
- /* Look for the connection header. If it's not found, return. */
- len = hashmap_entry_by_key(hashofheaders, headers[i], (void **)&data);
- if (len <= 0)
- return 0;
-
- /*
- * Go through the data line and replace any special characters
- * with a NULL.
- */
- ptr = data;
- while ((ptr = strpbrk(ptr, "()<>@,;:\\\"/[]?={} \t")))
- *ptr++ = '\0';
-
- /*
- * All the tokens are separated by NULLs. Now go through the
- * token and remove them from the hashofheaders.
- */
- ptr = data;
- while (ptr < data + len) {
- hashmap_remove(hashofheaders, ptr);
-
- /* Advance ptr to the next token */
- ptr += strlen(ptr) + 1;
- while (ptr < data + len && *ptr == '\0')
- ptr++;
- }
-
- /* Now remove the connection header it self. */
- hashmap_remove(hashofheaders, headers[i]);
- }
-
- return 0;
+ static char *headers[] = {
+ "connection",
+ "proxy-connection"
+ };
+
+ char *data;
+ char *ptr;
+ ssize_t len;
+ int i;
+
+ for (i = 0; i != (sizeof(headers) / sizeof(char *)); ++i) {
+ /* Look for the connection header. If it's not found, return. */
+ len =
+ hashmap_entry_by_key(hashofheaders, headers[i],
+ (void **)&data);
+ if (len <= 0)
+ return 0;
+
+ /*
+ * Go through the data line and replace any special characters
+ * with a NULL.
+ */
+ ptr = data;
+ while ((ptr = strpbrk(ptr, "()<>@,;:\\\"/[]?={} \t")))
+ *ptr++ = '\0';
+
+ /*
+ * All the tokens are separated by NULLs. Now go through the
+ * token and remove them from the hashofheaders.
+ */
+ ptr = data;
+ while (ptr < data + len) {
+ hashmap_remove(hashofheaders, ptr);
+
+ /* Advance ptr to the next token */
+ ptr += strlen(ptr) + 1;
+ while (ptr < data + len && *ptr == '\0')
+ ptr++;
+ }
+
+ /* Now remove the connection header it self. */
+ hashmap_remove(hashofheaders, headers[i]);
+ }
+
+ return 0;
}
/*
@@ -1132,15 +1162,17 @@ remove_connection_headers(hashmap_t hashofheaders)
static long
get_content_length(hashmap_t hashofheaders)
{
- ssize_t len;
- char *data;
- long content_length = -1;
+ ssize_t len;
+ char *data;
+ long content_length = -1;
- len = hashmap_entry_by_key(hashofheaders, "content-length", (void **)&data);
- if (len > 0)
- content_length = atol(data);
+ len =
+ hashmap_entry_by_key(hashofheaders, "content-length",
+ (void **)&data);
+ if (len > 0)
+ content_length = atol(data);
- return content_length;
+ return content_length;
}
/*
@@ -1152,40 +1184,38 @@ get_content_length(hashmap_t hashofheaders)
*/
static int
write_via_header(int fd, hashmap_t hashofheaders,
- unsigned int major, unsigned int minor)
+ unsigned int major, unsigned int minor)
{
- ssize_t len;
- char hostname[512];
- char *data;
- int ret;
-
- if (config.via_proxy_name) {
- strlcpy(hostname, config.via_proxy_name, sizeof(hostname));
- } else if (gethostname(hostname, sizeof(hostname)) < 0) {
- strcpy(hostname, "unknown");
- }
-
- /*
- * See if there is a "Via" header. If so, again we need to do a bit
- * of processing.
- */
- len = hashmap_entry_by_key(hashofheaders, "via", (void **)&data);
- if (len > 0) {
- ret = write_message(fd,
- "Via: %s, %hu.%hu %s (%s/%s)\r\n",
- data,
- major, minor,
- hostname, PACKAGE, VERSION);
-
- hashmap_remove(hashofheaders, "via");
- } else {
- ret = write_message(fd,
- "Via: %hu.%hu %s (%s/%s)\r\n",
- major, minor,
- hostname, PACKAGE, VERSION);
- }
-
- return ret;
+ ssize_t len;
+ char hostname[512];
+ char *data;
+ int ret;
+
+ if (config.via_proxy_name) {
+ strlcpy(hostname, config.via_proxy_name, sizeof(hostname));
+ } else if (gethostname(hostname, sizeof(hostname)) < 0) {
+ strcpy(hostname, "unknown");
+ }
+
+ /*
+ * See if there is a "Via" header. If so, again we need to do a bit
+ * of processing.
+ */
+ len = hashmap_entry_by_key(hashofheaders, "via", (void **)&data);
+ if (len > 0) {
+ ret = write_message(fd,
+ "Via: %s, %hu.%hu %s (%s/%s)\r\n",
+ data,
+ major, minor, hostname, PACKAGE, VERSION);
+
+ hashmap_remove(hashofheaders, "via");
+ } else {
+ ret = write_message(fd,
+ "Via: %hu.%hu %s (%s/%s)\r\n",
+ major, minor, hostname, PACKAGE, VERSION);
+ }
+
+ return ret;
}
/*
@@ -1202,107 +1232,108 @@ write_via_header(int fd, hashmap_t hashofheaders,
static int
process_client_headers(struct conn_s *connptr, hashmap_t hashofheaders)
{
- static char *skipheaders[] = {
- "host",
- "keep-alive",
- "proxy-connection",
- "te",
- "trailers",
- "transfer-encoding",
- "upgrade"
- };
- int i;
- hashmap_iter iter;
- int ret = 0;
-
- char *data, *header;
-
- /*
- * Don't send headers if there's already an error, if the request was
- * a stats request, or if this was a CONNECT method (unless upstream
- * proxy is in use.)
- */
- if (connptr->server_fd == -1 || connptr->show_stats
- || (connptr->connect_method && (connptr->upstream_proxy == NULL))) {
- log_message(LOG_INFO, "Not sending client headers to remote machine");
- return 0;
- }
-
- /*
- * See if there is a "Content-Length" header. If so, again we need
- * to do a bit of processing.
- */
- connptr->content_length.client = get_content_length(hashofheaders);
-
- /*
- * See if there is a "Connection" header. If so, we need to do a bit
- * of processing. :)
- */
- remove_connection_headers(hashofheaders);
-
- /*
- * Delete the headers listed in the skipheaders list
- */
- for (i = 0; i != (sizeof(skipheaders) / sizeof(char *)); i++) {
- hashmap_remove(hashofheaders, skipheaders[i]);
- }
-
- /* Send, or add the Via header */
- ret = write_via_header(connptr->server_fd, hashofheaders,
- connptr->protocol.major,
- connptr->protocol.minor);
- if (ret < 0) {
- indicate_http_error(connptr, 503,
- "Could not send data to remote server",
- "detail", "A network error occurred while trying to write data to the remote web server.",
- NULL);
- goto PULL_CLIENT_DATA;
- }
-
- /*
- * Output all the remaining headers to the remote machine.
- */
- iter = hashmap_first(hashofheaders);
- if (iter >= 0) {
- for ( ; !hashmap_is_end(hashofheaders, iter); ++iter) {
- hashmap_return_entry(hashofheaders,
- iter,
- &data,
- (void**)&header);
-
- if (!is_anonymous_enabled() || anonymous_search(data) > 0) {
- ret = write_message(connptr->server_fd,
- "%s: %s\r\n",
- data, header);
- if (ret < 0) {
- indicate_http_error(connptr, 503,
- "Could not send data to remote server",
- "detail", "A network error occurred while trying to write data to the remote web server.",
- NULL);
- goto PULL_CLIENT_DATA;
- }
- }
- }
- }
+ static char *skipheaders[] = {
+ "host",
+ "keep-alive",
+ "proxy-connection",
+ "te",
+ "trailers",
+ "transfer-encoding",
+ "upgrade"
+ };
+ int i;
+ hashmap_iter iter;
+ int ret = 0;
+
+ char *data, *header;
+
+ /*
+ * Don't send headers if there's already an error, if the request was
+ * a stats request, or if this was a CONNECT method (unless upstream
+ * proxy is in use.)
+ */
+ if (connptr->server_fd == -1 || connptr->show_stats
+ || (connptr->connect_method && (connptr->upstream_proxy == NULL))) {
+ log_message(LOG_INFO,
+ "Not sending client headers to remote machine");
+ return 0;
+ }
+
+ /*
+ * See if there is a "Content-Length" header. If so, again we need
+ * to do a bit of processing.
+ */
+ connptr->content_length.client = get_content_length(hashofheaders);
+
+ /*
+ * See if there is a "Connection" header. If so, we need to do a bit
+ * of processing. :)
+ */
+ remove_connection_headers(hashofheaders);
+
+ /*
+ * Delete the headers listed in the skipheaders list
+ */
+ for (i = 0; i != (sizeof(skipheaders) / sizeof(char *)); i++) {
+ hashmap_remove(hashofheaders, skipheaders[i]);
+ }
+ /* Send, or add the Via header */
+ ret = write_via_header(connptr->server_fd, hashofheaders,
+ connptr->protocol.major,
+ connptr->protocol.minor);
+ if (ret < 0) {
+ indicate_http_error(connptr, 503,
+ "Could not send data to remote server",
+ "detail",
+ "A network error occurred while trying to write data to the remote web server.",
+ NULL);
+ goto PULL_CLIENT_DATA;
+ }
+
+ /*
+ * Output all the remaining headers to the remote machine.
+ */
+ iter = hashmap_first(hashofheaders);
+ if (iter >= 0) {
+ for (; !hashmap_is_end(hashofheaders, iter); ++iter) {
+ hashmap_return_entry(hashofheaders,
+ iter, &data, (void **)&header);
+
+ if (!is_anonymous_enabled()
+ || anonymous_search(data) > 0) {
+ ret =
+ write_message(connptr->server_fd,
+ "%s: %s\r\n", data, header);
+ if (ret < 0) {
+ indicate_http_error(connptr, 503,
+ "Could not send data to remote server",
+ "detail",
+ "A network error occurred while trying to write data to the remote web server.",
+ NULL);
+ goto PULL_CLIENT_DATA;
+ }
+ }
+ }
+ }
#if defined(XTINYPROXY_ENABLE)
- if (config.my_domain)
- add_xtinyproxy_header(connptr);
+ if (config.my_domain)
+ add_xtinyproxy_header(connptr);
#endif
-
- /* Write the final "blank" line to signify the end of the headers */
- if (safe_write(connptr->server_fd, "\r\n", 2) < 0)
- return -1;
-
- /*
- * Spin here pulling the data from the client.
- */
- PULL_CLIENT_DATA:
- if (connptr->content_length.client > 0)
- return pull_client_data(connptr,
- connptr->content_length.client);
- else
- return ret;
+
+ /* Write the final "blank" line to signify the end of the headers */
+ if (safe_write(connptr->server_fd, "\r\n", 2) < 0)
+ return -1;
+
+ /*
+ * Spin here pulling the data from the client.
+ */
+ PULL_CLIENT_DATA:
+ if (connptr->content_length.client > 0)
+ return pull_client_data(connptr,
+ connptr->content_length.client);
+ else
+ return ret;
}
/*
@@ -1312,65 +1343,69 @@ process_client_headers(struct conn_s *connptr, hashmap_t hashofheaders)
static int
process_server_headers(struct conn_s *connptr)
{
- static char *skipheaders[] = {
- "keep-alive",
- "proxy-authenticate",
- "proxy-authorization",
- "proxy-connection",
- "transfer-encoding",
- };
-
- char *response_line;
-
- hashmap_t hashofheaders;
- hashmap_iter iter;
- char *data, *header;
- ssize_t len;
- int i;
- int ret;
+ static char *skipheaders[] = {
+ "keep-alive",
+ "proxy-authenticate",
+ "proxy-authorization",
+ "proxy-connection",
+ "transfer-encoding",
+ };
+
+ char *response_line;
+
+ hashmap_t hashofheaders;
+ hashmap_iter iter;
+ char *data, *header;
+ ssize_t len;
+ int i;
+ int ret;
#ifdef REVERSE_SUPPORT
- struct reversepath *reverse = config.reversepath_list;
+ struct reversepath *reverse = config.reversepath_list;
#endif
- /* Get the response line from the remote server. */
+ /* Get the response line from the remote server. */
retry:
- len = readline(connptr->server_fd, &response_line);
- if (len <= 0)
- return -1;
-
- /*
- * Strip the new line and character return from the string.
- */
- if (chomp(response_line, len) == len) {
- /*
- * If the number of characters removed is the same as the
- * length then it was a blank line. Free the buffer and
- * try again (since we're looking for a request line.)
- */
- safefree(response_line);
- goto retry;
- }
-
- hashofheaders = hashmap_create(HEADER_BUCKETS);
- if (!hashofheaders) {
- safefree(response_line);
- return -1;
- }
-
- /*
- * Get all the headers from the remote server in a big hash
- */
- if (get_all_headers(connptr->server_fd, hashofheaders) < 0) {
- log_message(LOG_WARNING, "Could not retrieve all the headers from the remote server.");
- hashmap_delete(hashofheaders);
- safefree(response_line);
-
- indicate_http_error(connptr, 503, "Could not retrieve all the headers",
- "detail", PACKAGE " was unable to retrieve and process headers from the remote web server.",
- NULL);
- return -1;
- }
+ len = readline(connptr->server_fd, &response_line);
+ if (len <= 0)
+ return -1;
+
+ /*
+ * Strip the new line and character return from the string.
+ */
+ if (chomp(response_line, len) == len) {
+ /*
+ * If the number of characters removed is the same as the
+ * length then it was a blank line. Free the buffer and
+ * try again (since we're looking for a request line.)
+ */
+ safefree(response_line);
+ goto retry;
+ }
+
+ hashofheaders = hashmap_create(HEADER_BUCKETS);
+ if (!hashofheaders) {
+ safefree(response_line);
+ return -1;
+ }
+
+ /*
+ * Get all the headers from the remote server in a big hash
+ */
+ if (get_all_headers(connptr->server_fd, hashofheaders) < 0) {
+ log_message(LOG_WARNING,
+ "Could not retrieve all the headers from the remote server.");
+ hashmap_delete(hashofheaders);
+ safefree(response_line);
+
+ indicate_http_error(connptr, 503,
+ "Could not retrieve all the headers",
+ "detail",
+ PACKAGE
+ " was unable to retrieve and process headers from the remote web server.",
+ NULL);
+ return -1;
+ }
/*
* At this point we've received the response line and all the
@@ -1384,103 +1419,106 @@ process_server_headers(struct conn_s *connptr)
return 0;
}
-
- /* Send the saved response line first */
+ /* Send the saved response line first */
ret = write_message(connptr->client_fd, "%s\r\n", response_line);
safefree(response_line);
if (ret < 0)
goto ERROR_EXIT;
- /*
- * If there is a "Content-Length" header, retrieve the information
- * from it for later use.
- */
- connptr->content_length.server = get_content_length(hashofheaders);
-
- /*
- * See if there is a connection header. If so, we need to to a bit of
- * processing.
- */
- remove_connection_headers(hashofheaders);
-
- /*
- * Delete the headers listed in the skipheaders list
- */
- for (i = 0; i != (sizeof(skipheaders) / sizeof(char *)); i++) {
- hashmap_remove(hashofheaders, skipheaders[i]);
- }
-
- /* Send, or add the Via header */
- ret = write_via_header(connptr->client_fd, hashofheaders,
- connptr->protocol.major,
- connptr->protocol.minor);
- if (ret < 0)
- goto ERROR_EXIT;
+ /*
+ * If there is a "Content-Length" header, retrieve the information
+ * from it for later use.
+ */
+ connptr->content_length.server = get_content_length(hashofheaders);
+
+ /*
+ * See if there is a connection header. If so, we need to to a bit of
+ * processing.
+ */
+ remove_connection_headers(hashofheaders);
+
+ /*
+ * Delete the headers listed in the skipheaders list
+ */
+ for (i = 0; i != (sizeof(skipheaders) / sizeof(char *)); i++) {
+ hashmap_remove(hashofheaders, skipheaders[i]);
+ }
+
+ /* Send, or add the Via header */
+ ret = write_via_header(connptr->client_fd, hashofheaders,
+ connptr->protocol.major,
+ connptr->protocol.minor);
+ if (ret < 0)
+ goto ERROR_EXIT;
#ifdef REVERSE_SUPPORT
- /* Write tracking cookie for the magical reverse proxy path hack */
- if (config.reversemagic && connptr->reversepath) {
- ret = write_message(connptr->client_fd,
- "Set-Cookie: " REVERSE_COOKIE "=%s; path=/\r\n",
- connptr->reversepath);
- if (ret < 0) goto ERROR_EXIT;
- }
-
- /* Rewrite the HTTP redirect if needed */
- if (config.reversebaseurl &&
- hashmap_entry_by_key(hashofheaders, "location", (void **)&header) > 0) {
-
- /* Look for a matching entry in the reversepath list */
- while (reverse) {
- if (strncasecmp(header,
- reverse->url,
- (len = strlen(reverse->url))) == 0) break;
- reverse = reverse->next;
- }
-
- if (reverse) {
- ret = write_message(connptr->client_fd, "Location: %s%s%s\r\n",
- config.reversebaseurl, (reverse->path + 1),
- (header + len));
- if (ret < 0) goto ERROR_EXIT;
-
- log_message(LOG_INFO,
- "Rewriting HTTP redirect: %s -> %s%s%s", header,
- config.reversebaseurl, (reverse->path + 1), (header + len));
- hashmap_remove(hashofheaders, "location");
- }
- }
+ /* Write tracking cookie for the magical reverse proxy path hack */
+ if (config.reversemagic && connptr->reversepath) {
+ ret = write_message(connptr->client_fd,
+ "Set-Cookie: " REVERSE_COOKIE
+ "=%s; path=/\r\n", connptr->reversepath);
+ if (ret < 0)
+ goto ERROR_EXIT;
+ }
+
+ /* Rewrite the HTTP redirect if needed */
+ if (config.reversebaseurl &&
+ hashmap_entry_by_key(hashofheaders, "location",
+ (void **)&header) > 0) {
+
+ /* Look for a matching entry in the reversepath list */
+ while (reverse) {
+ if (strncasecmp(header,
+ reverse->url,
+ (len = strlen(reverse->url))) == 0)
+ break;
+ reverse = reverse->next;
+ }
+
+ if (reverse) {
+ ret =
+ write_message(connptr->client_fd,
+ "Location: %s%s%s\r\n",
+ config.reversebaseurl,
+ (reverse->path + 1), (header + len));
+ if (ret < 0)
+ goto ERROR_EXIT;
+
+ log_message(LOG_INFO,
+ "Rewriting HTTP redirect: %s -> %s%s%s",
+ header, config.reversebaseurl,
+ (reverse->path + 1), (header + len));
+ hashmap_remove(hashofheaders, "location");
+ }
+ }
#endif
- /*
- * All right, output all the remaining headers to the client.
- */
- iter = hashmap_first(hashofheaders);
- if (iter >= 0) {
- for ( ; !hashmap_is_end(hashofheaders, iter); ++iter) {
- hashmap_return_entry(hashofheaders,
- iter,
- &data,
- (void **)&header);
-
- ret = write_message(connptr->client_fd,
- "%s: %s\r\n",
- data, header);
- if (ret < 0)
- goto ERROR_EXIT;
- }
- }
- hashmap_delete(hashofheaders);
-
- /* Write the final blank line to signify the end of the headers */
- if (safe_write(connptr->client_fd, "\r\n", 2) < 0)
- return -1;
-
- return 0;
-
- ERROR_EXIT:
- hashmap_delete(hashofheaders);
- return -1;
+ /*
+ * All right, output all the remaining headers to the client.
+ */
+ iter = hashmap_first(hashofheaders);
+ if (iter >= 0) {
+ for (; !hashmap_is_end(hashofheaders, iter); ++iter) {
+ hashmap_return_entry(hashofheaders,
+ iter, &data, (void **)&header);
+
+ ret = write_message(connptr->client_fd,
+ "%s: %s\r\n", data, header);
+ if (ret < 0)
+ goto ERROR_EXIT;
+ }
+ }
+ hashmap_delete(hashofheaders);
+
+ /* Write the final blank line to signify the end of the headers */
+ if (safe_write(connptr->client_fd, "\r\n", 2) < 0)
+ return -1;
+
+ return 0;
+
+ ERROR_EXIT:
+ hashmap_delete(hashofheaders);
+ return -1;
}
/*
@@ -1494,105 +1532,106 @@ process_server_headers(struct conn_s *connptr)
static void
relay_connection(struct conn_s *connptr)
{
- fd_set rset, wset;
- struct timeval tv;
- time_t last_access;
- int ret;
- double tdiff;
- int maxfd = max(connptr->client_fd, connptr->server_fd) + 1;
- ssize_t bytes_received;
-
- socket_nonblocking(connptr->client_fd);
- socket_nonblocking(connptr->server_fd);
-
- last_access = time(NULL);
-
- for (;;) {
- FD_ZERO(&rset);
- FD_ZERO(&wset);
-
- tv.tv_sec =
- config.idletimeout - difftime(time(NULL), last_access);
- tv.tv_usec = 0;
-
- if (buffer_size(connptr->sbuffer) > 0)
- FD_SET(connptr->client_fd, &wset);
- if (buffer_size(connptr->cbuffer) > 0)
- FD_SET(connptr->server_fd, &wset);
- if (buffer_size(connptr->sbuffer) < MAXBUFFSIZE)
- FD_SET(connptr->server_fd, &rset);
- if (buffer_size(connptr->cbuffer) < MAXBUFFSIZE)
- FD_SET(connptr->client_fd, &rset);
-
- ret = select(maxfd, &rset, &wset, NULL, &tv);
-
- if (ret == 0) {
- tdiff = difftime(time(NULL), last_access);
- if (tdiff > config.idletimeout) {
- log_message(LOG_INFO,
- "Idle Timeout (after select) as %g > %u.",
- tdiff, config.idletimeout);
- return;
- } else {
- continue;
- }
- } else if (ret < 0) {
- log_message(LOG_ERR,
- "relay_connection: select() error \"%s\". Closing connection (client_fd:%d, server_fd:%d)",
- strerror(errno), connptr->client_fd,
- connptr->server_fd);
- return;
- } else {
- /*
- * All right, something was actually selected so mark it.
- */
- last_access = time(NULL);
- }
-
- if (FD_ISSET(connptr->server_fd, &rset)) {
- bytes_received = read_buffer(connptr->server_fd, connptr->sbuffer);
- if (bytes_received < 0)
- break;
-
- connptr->content_length.server -= bytes_received;
- if (connptr->content_length.server == 0)
- break;
- }
- if (FD_ISSET(connptr->client_fd, &rset)
- && read_buffer(connptr->client_fd, connptr->cbuffer) < 0) {
- break;
- }
- if (FD_ISSET(connptr->server_fd, &wset)
- && write_buffer(connptr->server_fd, connptr->cbuffer) < 0) {
- break;
- }
- if (FD_ISSET(connptr->client_fd, &wset)
- && write_buffer(connptr->client_fd, connptr->sbuffer) < 0) {
- break;
- }
- }
-
- /*
- * Here the server has closed the connection... write the
- * remainder to the client and then exit.
- */
- socket_blocking(connptr->client_fd);
- while (buffer_size(connptr->sbuffer) > 0) {
- if (write_buffer(connptr->client_fd, connptr->sbuffer) < 0)
- break;
- }
- shutdown(connptr->client_fd, SHUT_WR);
-
- /*
- * Try to send any remaining data to the server if we can.
- */
- socket_blocking(connptr->server_fd);
- while (buffer_size(connptr->cbuffer) > 0) {
- if (write_buffer(connptr->server_fd, connptr->cbuffer) < 0)
- break;
- }
-
- return;
+ fd_set rset, wset;
+ struct timeval tv;
+ time_t last_access;
+ int ret;
+ double tdiff;
+ int maxfd = max(connptr->client_fd, connptr->server_fd) + 1;
+ ssize_t bytes_received;
+
+ socket_nonblocking(connptr->client_fd);
+ socket_nonblocking(connptr->server_fd);
+
+ last_access = time(NULL);
+
+ for (;;) {
+ FD_ZERO(&rset);
+ FD_ZERO(&wset);
+
+ tv.tv_sec =
+ config.idletimeout - difftime(time(NULL), last_access);
+ tv.tv_usec = 0;
+
+ if (buffer_size(connptr->sbuffer) > 0)
+ FD_SET(connptr->client_fd, &wset);
+ if (buffer_size(connptr->cbuffer) > 0)
+ FD_SET(connptr->server_fd, &wset);
+ if (buffer_size(connptr->sbuffer) < MAXBUFFSIZE)
+ FD_SET(connptr->server_fd, &rset);
+ if (buffer_size(connptr->cbuffer) < MAXBUFFSIZE)
+ FD_SET(connptr->client_fd, &rset);
+
+ ret = select(maxfd, &rset, &wset, NULL, &tv);
+
+ if (ret == 0) {
+ tdiff = difftime(time(NULL), last_access);
+ if (tdiff > config.idletimeout) {
+ log_message(LOG_INFO,
+ "Idle Timeout (after select) as %g > %u.",
+ tdiff, config.idletimeout);
+ return;
+ } else {
+ continue;
+ }
+ } else if (ret < 0) {
+ log_message(LOG_ERR,
+ "relay_connection: select() error \"%s\". Closing connection (client_fd:%d, server_fd:%d)",
+ strerror(errno), connptr->client_fd,
+ connptr->server_fd);
+ return;
+ } else {
+ /*
+ * All right, something was actually selected so mark it.
+ */
+ last_access = time(NULL);
+ }
+
+ if (FD_ISSET(connptr->server_fd, &rset)) {
+ bytes_received =
+ read_buffer(connptr->server_fd, connptr->sbuffer);
+ if (bytes_received < 0)
+ break;
+
+ connptr->content_length.server -= bytes_received;
+ if (connptr->content_length.server == 0)
+ break;
+ }
+ if (FD_ISSET(connptr->client_fd, &rset)
+ && read_buffer(connptr->client_fd, connptr->cbuffer) < 0) {
+ break;
+ }
+ if (FD_ISSET(connptr->server_fd, &wset)
+ && write_buffer(connptr->server_fd, connptr->cbuffer) < 0) {
+ break;
+ }
+ if (FD_ISSET(connptr->client_fd, &wset)
+ && write_buffer(connptr->client_fd, connptr->sbuffer) < 0) {
+ break;
+ }
+ }
+
+ /*
+ * Here the server has closed the connection... write the
+ * remainder to the client and then exit.
+ */
+ socket_blocking(connptr->client_fd);
+ while (buffer_size(connptr->sbuffer) > 0) {
+ if (write_buffer(connptr->client_fd, connptr->sbuffer) < 0)
+ break;
+ }
+ shutdown(connptr->client_fd, SHUT_WR);
+
+ /*
+ * Try to send any remaining data to the server if we can.
+ */
+ socket_blocking(connptr->server_fd);
+ while (buffer_size(connptr->cbuffer) > 0) {
+ if (write_buffer(connptr->server_fd, connptr->cbuffer) < 0)
+ break;
+ }
+
+ return;
}
/*
@@ -1602,71 +1641,75 @@ static int
connect_to_upstream(struct conn_s *connptr, struct request_s *request)
{
#ifndef UPSTREAM_SUPPORT
- /*
- * This function does nothing if upstream support was not compiled
- * into tinyproxy.
- */
- return -1;
+ /*
+ * This function does nothing if upstream support was not compiled
+ * into tinyproxy.
+ */
+ return -1;
#else
- char *combined_string;
- int len;
-
- struct upstream *cur_upstream = connptr->upstream_proxy;
- if(!cur_upstream) {
- log_message(LOG_WARNING,
- "No upstream proxy defined for %s.",
- request->host);
- indicate_http_error(connptr, 404, "Unable to connect to upstream proxy.");
- return -1;
- }
-
- connptr->server_fd =
- opensock(cur_upstream->host, cur_upstream->port, connptr->server_ip_addr);
-
- if (connptr->server_fd < 0) {
- log_message(LOG_WARNING,
- "Could not connect to upstream proxy.");
- indicate_http_error(connptr, 404, "Unable to connect to upstream proxy",
- "detail", "A network error occurred while trying to connect to the upstream web proxy.",
- NULL);
- return -1;
- }
-
- log_message(LOG_CONN,
- "Established connection to upstream proxy \"%s\" using file descriptor %d.",
- cur_upstream->host, connptr->server_fd);
-
- /*
- * We need to re-write the "path" part of the request so that we
- * can reuse the establish_http_connection() function. It expects a
- * method and path.
- */
- if (connptr->connect_method) {
- len = strlen(request->host) + 7;
-
- combined_string = safemalloc(len);
- if (!combined_string) {
- return -1;
- }
-
- snprintf(combined_string, len, "%s:%d", request->host,
- request->port);
- } else {
- len = strlen(request->host) + strlen(request->path) + 14;
- combined_string = safemalloc(len);
- if (!combined_string) {
- return -1;
- }
-
- snprintf(combined_string, len, "http://%s:%d%s", request->host,
- request->port, request->path);
- }
-
- if (request->path)
- safefree(request->path);
- request->path = combined_string;
-
- return establish_http_connection(connptr, request);
+ char *combined_string;
+ int len;
+
+ struct upstream *cur_upstream = connptr->upstream_proxy;
+
+ if (!cur_upstream) {
+ log_message(LOG_WARNING,
+ "No upstream proxy defined for %s.", request->host);
+ indicate_http_error(connptr, 404,
+ "Unable to connect to upstream proxy.");
+ return -1;
+ }
+
+ connptr->server_fd =
+ opensock(cur_upstream->host, cur_upstream->port,
+ connptr->server_ip_addr);
+
+ if (connptr->server_fd < 0) {
+ log_message(LOG_WARNING,
+ "Could not connect to upstream proxy.");
+ indicate_http_error(connptr, 404,
+ "Unable to connect to upstream proxy",
+ "detail",
+ "A network error occurred while trying to connect to the upstream web proxy.",
+ NULL);
+ return -1;
+ }
+
+ log_message(LOG_CONN,
+ "Established connection to upstream proxy \"%s\" using file descriptor %d.",
+ cur_upstream->host, connptr->server_fd);
+
+ /*
+ * We need to re-write the "path" part of the request so that we
+ * can reuse the establish_http_connection() function. It expects a
+ * method and path.
+ */
+ if (connptr->connect_method) {
+ len = strlen(request->host) + 7;
+
+ combined_string = safemalloc(len);
+ if (!combined_string) {
+ return -1;
+ }
+
+ snprintf(combined_string, len, "%s:%d", request->host,
+ request->port);
+ } else {
+ len = strlen(request->host) + strlen(request->path) + 14;
+ combined_string = safemalloc(len);
+ if (!combined_string) {
+ return -1;
+ }
+
+ snprintf(combined_string, len, "http://%s:%d%s", request->host,
+ request->port, request->path);
+ }
+
+ if (request->path)
+ safefree(request->path);
+ request->path = combined_string;
+
+ return establish_http_connection(connptr, request);
#endif
}
@@ -1682,112 +1725,117 @@ connect_to_upstream(struct conn_s *connptr, struct request_s *request)
void
handle_connection(int fd)
{
- struct conn_s *connptr;
- struct request_s *request = NULL;
- hashmap_t hashofheaders = NULL;
-
- char sock_ipaddr[IP_LENGTH];
- char peer_ipaddr[IP_LENGTH];
- char peer_string[HOSTNAME_LENGTH];
-
- getpeer_information(fd, peer_ipaddr, peer_string);
-
- if (config.bindsame)
- getsock_ip(fd, sock_ipaddr);
-
- log_message(LOG_CONN, config.bindsame ?
- "Connect (file descriptor %d): %s [%s] at [%s]" :
- "Connect (file descriptor %d): %s [%s]",
- fd, peer_string, peer_ipaddr, sock_ipaddr);
-
- connptr = initialize_conn(fd, peer_ipaddr, peer_string,
- config.bindsame ? sock_ipaddr : 0);
- if (!connptr) {
- close(fd);
- return;
- }
-
- if (check_acl(fd, peer_ipaddr, peer_string) <= 0) {
- update_stats(STAT_DENIED);
- indicate_http_error(connptr, 403, "Access denied",
- "detail", "The administrator of this proxy has not configured it to service requests from your host.",
- NULL);
- send_http_error_message(connptr);
- destroy_conn(connptr);
- return;
- }
-
- if (read_request_line(connptr) < 0) {
- update_stats(STAT_BADCONN);
- indicate_http_error(connptr, 408, "Timeout",
- "detail", "Server timeout waiting for the HTTP request from the client.",
- NULL);
- send_http_error_message(connptr);
- destroy_conn(connptr);
- return;
- }
-
- /*
- * The "hashofheaders" store the client's headers.
- */
- if (!(hashofheaders = hashmap_create(HEADER_BUCKETS))) {
- update_stats(STAT_BADCONN);
- indicate_http_error(connptr, 503, "Internal error",
- "detail", "An internal server error occurred while processing your request. Please contact the administrator.",
- NULL);
- send_http_error_message(connptr);
- destroy_conn(connptr);
- return;
- }
-
- /*
- * Get all the headers from the client in a big hash.
- */
- if (get_all_headers(connptr->client_fd, hashofheaders) < 0) {
- log_message(LOG_WARNING, "Could not retrieve all the headers from the client");
- hashmap_delete(hashofheaders);
- update_stats(STAT_BADCONN);
- destroy_conn(connptr);
- return;
- }
-
- request = process_request(connptr, hashofheaders);
- if (!request) {
- if (!connptr->error_variables && !connptr->show_stats) {
- update_stats(STAT_BADCONN);
- destroy_conn(connptr);
- hashmap_delete(hashofheaders);
- return;
- }
- goto send_error;
- }
-
- connptr->upstream_proxy = UPSTREAM_HOST(request->host);
- if (connptr->upstream_proxy != NULL) {
- if (connect_to_upstream(connptr, request) < 0) {
- goto send_error;
- }
- } else {
- connptr->server_fd = opensock(request->host, request->port,
- connptr->server_ip_addr);
- if (connptr->server_fd < 0) {
- indicate_http_error(connptr, 500, "Unable to connect",
- "detail", PACKAGE " was unable to connect to the remote web server.",
- "error", strerror(errno),
- NULL);
- goto send_error;
- }
-
- log_message(LOG_CONN,
- "Established connection to host \"%s\" using file descriptor %d.",
- request->host, connptr->server_fd);
-
- if (!connptr->connect_method)
- establish_http_connection(connptr, request);
- }
+ struct conn_s *connptr;
+ struct request_s *request = NULL;
+ hashmap_t hashofheaders = NULL;
+
+ char sock_ipaddr[IP_LENGTH];
+ char peer_ipaddr[IP_LENGTH];
+ char peer_string[HOSTNAME_LENGTH];
+
+ getpeer_information(fd, peer_ipaddr, peer_string);
+
+ if (config.bindsame)
+ getsock_ip(fd, sock_ipaddr);
+
+ log_message(LOG_CONN, config.bindsame ?
+ "Connect (file descriptor %d): %s [%s] at [%s]" :
+ "Connect (file descriptor %d): %s [%s]",
+ fd, peer_string, peer_ipaddr, sock_ipaddr);
+
+ connptr = initialize_conn(fd, peer_ipaddr, peer_string,
+ config.bindsame ? sock_ipaddr : 0);
+ if (!connptr) {
+ close(fd);
+ return;
+ }
+
+ if (check_acl(fd, peer_ipaddr, peer_string) <= 0) {
+ update_stats(STAT_DENIED);
+ indicate_http_error(connptr, 403, "Access denied",
+ "detail",
+ "The administrator of this proxy has not configured it to service requests from your host.",
+ NULL);
+ send_http_error_message(connptr);
+ destroy_conn(connptr);
+ return;
+ }
+
+ if (read_request_line(connptr) < 0) {
+ update_stats(STAT_BADCONN);
+ indicate_http_error(connptr, 408, "Timeout",
+ "detail",
+ "Server timeout waiting for the HTTP request from the client.",
+ NULL);
+ send_http_error_message(connptr);
+ destroy_conn(connptr);
+ return;
+ }
+
+ /*
+ * The "hashofheaders" store the client's headers.
+ */
+ if (!(hashofheaders = hashmap_create(HEADER_BUCKETS))) {
+ update_stats(STAT_BADCONN);
+ indicate_http_error(connptr, 503, "Internal error",
+ "detail",
+ "An internal server error occurred while processing your request. Please contact the administrator.",
+ NULL);
+ send_http_error_message(connptr);
+ destroy_conn(connptr);
+ return;
+ }
+
+ /*
+ * Get all the headers from the client in a big hash.
+ */
+ if (get_all_headers(connptr->client_fd, hashofheaders) < 0) {
+ log_message(LOG_WARNING,
+ "Could not retrieve all the headers from the client");
+ hashmap_delete(hashofheaders);
+ update_stats(STAT_BADCONN);
+ destroy_conn(connptr);
+ return;
+ }
+
+ request = process_request(connptr, hashofheaders);
+ if (!request) {
+ if (!connptr->error_variables && !connptr->show_stats) {
+ update_stats(STAT_BADCONN);
+ destroy_conn(connptr);
+ hashmap_delete(hashofheaders);
+ return;
+ }
+ goto send_error;
+ }
+
+ connptr->upstream_proxy = UPSTREAM_HOST(request->host);
+ if (connptr->upstream_proxy != NULL) {
+ if (connect_to_upstream(connptr, request) < 0) {
+ goto send_error;
+ }
+ } else {
+ connptr->server_fd = opensock(request->host, request->port,
+ connptr->server_ip_addr);
+ if (connptr->server_fd < 0) {
+ indicate_http_error(connptr, 500, "Unable to connect",
+ "detail",
+ PACKAGE
+ " was unable to connect to the remote web server.",
+ "error", strerror(errno), NULL);
+ goto send_error;
+ }
+
+ log_message(LOG_CONN,
+ "Established connection to host \"%s\" using file descriptor %d.",
+ request->host, connptr->server_fd);
+
+ if (!connptr->connect_method)
+ establish_http_connection(connptr, request);
+ }
send_error:
- free_request_struct(request);
+ free_request_struct(request);
if (process_client_headers(connptr, hashofheaders) < 0) {
update_stats(STAT_BADCONN);
@@ -1799,43 +1847,44 @@ handle_connection(int fd)
}
hashmap_delete(hashofheaders);
- if (connptr->error_variables) {
- send_http_error_message(connptr);
- destroy_conn(connptr);
- return;
- } else if (connptr->show_stats) {
- showstats(connptr);
- destroy_conn(connptr);
- return;
- }
-
- if (!connptr->connect_method || (connptr->upstream_proxy != NULL)) {
- if (process_server_headers(connptr) < 0) {
- if (connptr->error_variables)
- send_http_error_message(connptr);
-
- update_stats(STAT_BADCONN);
- destroy_conn(connptr);
- return;
- }
- } else {
- if (send_ssl_response(connptr) < 0) {
- log_message(LOG_ERR,
- "handle_connection: Could not send SSL greeting to client.");
- update_stats(STAT_BADCONN);
- destroy_conn(connptr);
- return;
- }
- }
-
- relay_connection(connptr);
-
- log_message(LOG_INFO, "Closed connection between local client (fd:%d) and remote client (fd:%d)",
- connptr->client_fd, connptr->server_fd);
-
- /*
- * All done... close everything and go home... :)
- */
- destroy_conn(connptr);
- return;
+ if (connptr->error_variables) {
+ send_http_error_message(connptr);
+ destroy_conn(connptr);
+ return;
+ } else if (connptr->show_stats) {
+ showstats(connptr);
+ destroy_conn(connptr);
+ return;
+ }
+
+ if (!connptr->connect_method || (connptr->upstream_proxy != NULL)) {
+ if (process_server_headers(connptr) < 0) {
+ if (connptr->error_variables)
+ send_http_error_message(connptr);
+
+ update_stats(STAT_BADCONN);
+ destroy_conn(connptr);
+ return;
+ }
+ } else {
+ if (send_ssl_response(connptr) < 0) {
+ log_message(LOG_ERR,
+ "handle_connection: Could not send SSL greeting to client.");
+ update_stats(STAT_BADCONN);
+ destroy_conn(connptr);
+ return;
+ }
+ }
+
+ relay_connection(connptr);
+
+ log_message(LOG_INFO,
+ "Closed connection between local client (fd:%d) and remote client (fd:%d)",
+ connptr->client_fd, connptr->server_fd);
+
+ /*
+ * All done... close everything and go home... :)
+ */
+ destroy_conn(connptr);
+ return;
}
diff --git a/src/sock.c b/src/sock.c
index 977a48e..d62657d 100644
--- a/src/sock.c
+++ b/src/sock.c
@@ -1,4 +1,4 @@
-/* $Id: sock.c,v 1.42 2005-07-12 20:34:26 rjkaes Exp $
+/* $Id: sock.c,v 1.43 2005-08-15 03:54:31 rjkaes Exp $
*
* Sockets are created and destroyed here. When a new connection comes in from
* a client, we need to copy the socket and the create a second socket to the
@@ -35,34 +35,34 @@
* to indicate an error.
*/
static int
-bind_socket(int sockfd, const char* addr)
+bind_socket(int sockfd, const char *addr)
{
- struct addrinfo hints, *res, *ressave;
+ struct addrinfo hints, *res, *ressave;
- assert(sockfd >= 0);
- assert(addr != NULL && strlen(addr) != 0);
+ assert(sockfd >= 0);
+ assert(addr != NULL && strlen(addr) != 0);
- memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
- /* The local port it not important */
- if (getaddrinfo(addr, NULL, &hints, &res) != 0)
- return -1;
+ /* The local port it not important */
+ if (getaddrinfo(addr, NULL, &hints, &res) != 0)
+ return -1;
- ressave = res;
+ ressave = res;
- /* Loop through the addresses and try to bind to each */
- do {
- if (bind(sockfd, res->ai_addr, res->ai_addrlen) == 0)
- break; /* success */
- } while ((res = res->ai_next) != NULL);
+ /* Loop through the addresses and try to bind to each */
+ do {
+ if (bind(sockfd, res->ai_addr, res->ai_addrlen) == 0)
+ break; /* success */
+ } while ((res = res->ai_next) != NULL);
- freeaddrinfo(ressave);
- if (res == NULL) /* was not able to bind to any address */
- return -1;
+ freeaddrinfo(ressave);
+ if (res == NULL) /* was not able to bind to any address */
+ return -1;
- return sockfd;
+ return sockfd;
}
/*
@@ -71,62 +71,63 @@ bind_socket(int sockfd, const char* addr)
* independent implementation (mostly for IPv4 and IPv6 addresses.)
*/
int
-opensock(const char* host, int port, const char* bind_to)
+opensock(const char *host, int port, const char *bind_to)
{
- int sockfd, n;
- struct addrinfo hints, *res, *ressave;
- char portstr[6];
-
- assert(host != NULL);
- assert(port > 0);
-
- memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
-
- snprintf(portstr, sizeof(portstr), "%d", port);
-
- n = getaddrinfo(host, portstr, &hints, &res);
- if (n != 0) {
- log_message(LOG_ERR, "opensock: Could not retrieve info for %s",
- host);
- return -1;
- }
-
- ressave = res;
- do {
- sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
- if (sockfd < 0)
- continue; /* ignore this one */
-
- /* Bind to the specified address */
- if (bind_to) {
- if (bind_socket(sockfd, bind_to) < 0) {
- close(sockfd);
- continue; /* can't bind, so try again */
- }
- } else if (config.bind_address) {
- if (bind_socket(sockfd, config.bind_address) < 0) {
- close(sockfd);
- continue; /* can't bind, so try again */
- }
- }
-
- if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)
- break; /* success */
-
- close(sockfd);
- } while ((res = res->ai_next) != NULL);
-
- freeaddrinfo(ressave);
- if (res == NULL) {
- log_message(LOG_ERR,
- "opensock: Could not establish a connection to %s",
- host);
- return -1;
- }
-
- return sockfd;
+ int sockfd, n;
+ struct addrinfo hints, *res, *ressave;
+ char portstr[6];
+
+ assert(host != NULL);
+ assert(port > 0);
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+
+ snprintf(portstr, sizeof(portstr), "%d", port);
+
+ n = getaddrinfo(host, portstr, &hints, &res);
+ if (n != 0) {
+ log_message(LOG_ERR, "opensock: Could not retrieve info for %s",
+ host);
+ return -1;
+ }
+
+ ressave = res;
+ do {
+ sockfd =
+ socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (sockfd < 0)
+ continue; /* ignore this one */
+
+ /* Bind to the specified address */
+ if (bind_to) {
+ if (bind_socket(sockfd, bind_to) < 0) {
+ close(sockfd);
+ continue; /* can't bind, so try again */
+ }
+ } else if (config.bind_address) {
+ if (bind_socket(sockfd, config.bind_address) < 0) {
+ close(sockfd);
+ continue; /* can't bind, so try again */
+ }
+ }
+
+ if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)
+ break; /* success */
+
+ close(sockfd);
+ } while ((res = res->ai_next) != NULL);
+
+ freeaddrinfo(ressave);
+ if (res == NULL) {
+ log_message(LOG_ERR,
+ "opensock: Could not establish a connection to %s",
+ host);
+ return -1;
+ }
+
+ return sockfd;
}
/*
@@ -135,12 +136,12 @@ opensock(const char* host, int port, const char* bind_to)
int
socket_nonblocking(int sock)
{
- int flags;
+ int flags;
- assert(sock >= 0);
+ assert(sock >= 0);
- flags = fcntl(sock, F_GETFL, 0);
- return fcntl(sock, F_SETFL, flags | O_NONBLOCK);
+ flags = fcntl(sock, F_GETFL, 0);
+ return fcntl(sock, F_SETFL, flags | O_NONBLOCK);
}
/*
@@ -149,12 +150,12 @@ socket_nonblocking(int sock)
int
socket_blocking(int sock)
{
- int flags;
+ int flags;
- assert(sock >= 0);
+ assert(sock >= 0);
- flags = fcntl(sock, F_GETFL, 0);
- return fcntl(sock, F_SETFL, flags & ~O_NONBLOCK);
+ flags = fcntl(sock, F_GETFL, 0);
+ return fcntl(sock, F_SETFL, flags & ~O_NONBLOCK);
}
/*
@@ -164,94 +165,95 @@ socket_blocking(int sock)
* - rjkaes
*/
int
-listen_sock(uint16_t port, socklen_t* addrlen)
+listen_sock(uint16_t port, socklen_t * addrlen)
{
- int listenfd;
- const int on = 1;
- struct sockaddr_in addr;
-
- assert(port > 0);
- assert(addrlen != NULL);
-
- listenfd = socket(AF_INET, SOCK_STREAM, 0);
- setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
-
- if (config.ipAddr) {
- addr.sin_addr.s_addr = inet_addr(config.ipAddr);
- } else {
- addr.sin_addr.s_addr = inet_addr("0.0.0.0");
- }
-
- if (bind(listenfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- log_message(LOG_ERR, "Unable to bind listening socket because of %s",
- strerror(errno));
- return -1;
- }
-
- if (listen(listenfd, MAXLISTEN) < 0) {
- log_message(LOG_ERR, "Unable to start listening socket because of %s",
- strerror(errno));
- return -1;
- }
-
- *addrlen = sizeof(addr);
-
- return listenfd;
+ int listenfd;
+ const int on = 1;
+ struct sockaddr_in addr;
+
+ assert(port > 0);
+ assert(addrlen != NULL);
+
+ listenfd = socket(AF_INET, SOCK_STREAM, 0);
+ setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+
+ if (config.ipAddr) {
+ addr.sin_addr.s_addr = inet_addr(config.ipAddr);
+ } else {
+ addr.sin_addr.s_addr = inet_addr("0.0.0.0");
+ }
+
+ if (bind(listenfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ log_message(LOG_ERR,
+ "Unable to bind listening socket because of %s",
+ strerror(errno));
+ return -1;
+ }
+
+ if (listen(listenfd, MAXLISTEN) < 0) {
+ log_message(LOG_ERR,
+ "Unable to start listening socket because of %s",
+ strerror(errno));
+ return -1;
+ }
+
+ *addrlen = sizeof(addr);
+
+ return listenfd;
}
/*
* Takes a socket descriptor and returns the socket's IP address.
*/
int
-getsock_ip(int fd, char* ipaddr)
+getsock_ip(int fd, char *ipaddr)
{
- struct sockaddr_storage name;
- socklen_t namelen = sizeof(name);
+ struct sockaddr_storage name;
+ socklen_t namelen = sizeof(name);
- assert(fd >= 0);
+ assert(fd >= 0);
- if (getsockname(fd, (struct sockaddr *) &name, &namelen) != 0) {
- log_message(LOG_ERR, "getsock_ip: getsockname() error: %s",
- strerror(errno));
- return -1;
- }
+ if (getsockname(fd, (struct sockaddr *)&name, &namelen) != 0) {
+ log_message(LOG_ERR, "getsock_ip: getsockname() error: %s",
+ strerror(errno));
+ return -1;
+ }
- if (get_ip_string((struct sockaddr *)&name, ipaddr, IP_LENGTH) == NULL)
- return -1;
+ if (get_ip_string((struct sockaddr *)&name, ipaddr, IP_LENGTH) == NULL)
+ return -1;
- return 0;
+ return 0;
}
/*
* Return the peer's socket information.
*/
int
-getpeer_information(int fd, char* ipaddr, char* string_addr)
+getpeer_information(int fd, char *ipaddr, char *string_addr)
{
- struct sockaddr_storage sa;
- size_t salen = sizeof(sa);
+ struct sockaddr_storage sa;
+ size_t salen = sizeof(sa);
- assert(fd >= 0);
- assert(ipaddr != NULL);
- assert(string_addr != NULL);
+ assert(fd >= 0);
+ assert(ipaddr != NULL);
+ assert(string_addr != NULL);
- /* Set the strings to default values */
- ipaddr[0] = '\0';
- strlcpy(string_addr, "[unknown]", HOSTNAME_LENGTH);
+ /* Set the strings to default values */
+ ipaddr[0] = '\0';
+ strlcpy(string_addr, "[unknown]", HOSTNAME_LENGTH);
- /* Look up the IP address */
- if (getpeername(fd, (struct sockaddr *)&sa, &salen) != 0)
- return -1;
+ /* Look up the IP address */
+ if (getpeername(fd, (struct sockaddr *)&sa, &salen) != 0)
+ return -1;
- if (get_ip_string((struct sockaddr *)&sa, ipaddr, IP_LENGTH) == NULL)
- return -1;
+ if (get_ip_string((struct sockaddr *)&sa, ipaddr, IP_LENGTH) == NULL)
+ return -1;
- /* Get the full host name */
- return getnameinfo((struct sockaddr *)&sa, salen,
- string_addr, HOSTNAME_LENGTH,
- NULL, 0, 0);
+ /* Get the full host name */
+ return getnameinfo((struct sockaddr *)&sa, salen,
+ string_addr, HOSTNAME_LENGTH, NULL, 0, 0);
}
diff --git a/src/sock.h b/src/sock.h
index b0c1a96..0b5d08a 100644
--- a/src/sock.h
+++ b/src/sock.h
@@ -1,4 +1,4 @@
-/* $Id: sock.h,v 1.13 2004-04-27 18:53:14 rjkaes Exp $
+/* $Id: sock.h,v 1.14 2005-08-15 03:54:31 rjkaes Exp $
*
* See 'sock.c' for a detailed description.
*
@@ -25,13 +25,13 @@
#define MAXLINE (1024 * 4)
-extern int opensock(const char* host, int port, const char* bind_to);
-extern int listen_sock(uint16_t port, socklen_t* addrlen);
+extern int opensock(const char *host, int port, const char *bind_to);
+extern int listen_sock(uint16_t port, socklen_t * addrlen);
extern int socket_nonblocking(int sock);
extern int socket_blocking(int sock);
-extern int getsock_ip(int fd, char* ipaddr);
-extern int getpeer_information(int fd, char* ipaddr, char* string_addr);
+extern int getsock_ip(int fd, char *ipaddr);
+extern int getpeer_information(int fd, char *ipaddr, char *string_addr);
#endif
diff --git a/src/stats.c b/src/stats.c
index e863521..1ffeaff 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -1,4 +1,4 @@
-/* $Id: stats.c,v 1.17 2005-07-12 17:39:44 rjkaes Exp $
+/* $Id: stats.c,v 1.18 2005-08-15 03:54:31 rjkaes Exp $
*
* This module handles the statistics for tinyproxy. There are only two
* public API functions. The reason for the functions, rather than just a
@@ -30,11 +30,11 @@
#include "utils.h"
struct stat_s {
- unsigned long int num_reqs;
- unsigned long int num_badcons;
- unsigned long int num_open;
- unsigned long int num_refused;
- unsigned long int num_denied;
+ unsigned long int num_reqs;
+ unsigned long int num_badcons;
+ unsigned long int num_open;
+ unsigned long int num_refused;
+ unsigned long int num_denied;
};
static struct stat_s *stats;
@@ -45,11 +45,11 @@ static struct stat_s *stats;
void
init_stats(void)
{
- stats = malloc_shared_memory(sizeof(struct stat_s));
- if (stats == MAP_FAILED)
- return;
+ stats = malloc_shared_memory(sizeof(struct stat_s));
+ if (stats == MAP_FAILED)
+ return;
- memset(stats, 0, sizeof(struct stat_s));
+ memset(stats, 0, sizeof(struct stat_s));
}
/*
@@ -58,59 +58,60 @@ init_stats(void)
int
showstats(struct conn_s *connptr)
{
- static char *msg =
- "<html><head><title>%s (%s) stats</title></head>\r\n"
- "<body>\r\n"
- "<center><h2>%s (%s) run-time statistics</h2></center><hr>\r\n"
- "<blockquote>\r\n"
- "Number of open connections: %lu<br>\r\n"
- "Number of requests: %lu<br>\r\n"
- "Number of bad connections: %lu<br>\r\n"
- "Number of denied connections: %lu<br>\r\n"
- "Number of refused connections due to high load: %lu\r\n"
- "</blockquote>\r\n</body></html>\r\n";
-
- char *message_buffer;
- char opens[16], reqs[16], badconns[16], denied[16], refused[16];
- FILE *statfile;
-
- snprintf(opens, sizeof(opens), "%lu", stats->num_open);
- snprintf(reqs, sizeof(reqs), "%lu", stats->num_reqs);
- snprintf(badconns, sizeof(badconns), "%lu", stats->num_badcons);
- snprintf(denied, sizeof(denied), "%lu", stats->num_denied);
- snprintf(refused, sizeof(refused), "%lu", stats->num_refused);
-
- if (!config.statpage || (!(statfile = fopen(config.statpage, "r")))) {
- message_buffer = safemalloc(MAXBUFFSIZE);
- if (!message_buffer)
- return -1;
-
- snprintf(message_buffer, MAXBUFFSIZE, msg,
- PACKAGE, VERSION, PACKAGE, VERSION,
- stats->num_open,
- stats->num_reqs,
- stats->num_badcons, stats->num_denied, stats->num_refused);
-
- if (send_http_message(connptr, 200, "OK", message_buffer) < 0) {
- safefree(message_buffer);
- return -1;
- }
-
- safefree(message_buffer);
- return 0;
- }
-
- add_error_variable(connptr, "opens", opens);
- add_error_variable(connptr, "reqs", reqs);
- add_error_variable(connptr, "badconns", badconns);
- add_error_variable(connptr, "denied", denied);
- add_error_variable(connptr, "refused", refused);
- add_standard_vars(connptr);
- send_http_headers(connptr, 200, "Statistic requested");
- send_html_file(statfile, connptr);
- fclose(statfile);
-
- return 0;
+ static char *msg =
+ "<html><head><title>%s (%s) stats</title></head>\r\n"
+ "<body>\r\n"
+ "<center><h2>%s (%s) run-time statistics</h2></center><hr>\r\n"
+ "<blockquote>\r\n"
+ "Number of open connections: %lu<br>\r\n"
+ "Number of requests: %lu<br>\r\n"
+ "Number of bad connections: %lu<br>\r\n"
+ "Number of denied connections: %lu<br>\r\n"
+ "Number of refused connections due to high load: %lu\r\n"
+ "</blockquote>\r\n</body></html>\r\n";
+
+ char *message_buffer;
+ char opens[16], reqs[16], badconns[16], denied[16], refused[16];
+ FILE *statfile;
+
+ snprintf(opens, sizeof(opens), "%lu", stats->num_open);
+ snprintf(reqs, sizeof(reqs), "%lu", stats->num_reqs);
+ snprintf(badconns, sizeof(badconns), "%lu", stats->num_badcons);
+ snprintf(denied, sizeof(denied), "%lu", stats->num_denied);
+ snprintf(refused, sizeof(refused), "%lu", stats->num_refused);
+
+ if (!config.statpage || (!(statfile = fopen(config.statpage, "r")))) {
+ message_buffer = safemalloc(MAXBUFFSIZE);
+ if (!message_buffer)
+ return -1;
+
+ snprintf(message_buffer, MAXBUFFSIZE, msg,
+ PACKAGE, VERSION, PACKAGE, VERSION,
+ stats->num_open,
+ stats->num_reqs,
+ stats->num_badcons, stats->num_denied,
+ stats->num_refused);
+
+ if (send_http_message(connptr, 200, "OK", message_buffer) < 0) {
+ safefree(message_buffer);
+ return -1;
+ }
+
+ safefree(message_buffer);
+ return 0;
+ }
+
+ add_error_variable(connptr, "opens", opens);
+ add_error_variable(connptr, "reqs", reqs);
+ add_error_variable(connptr, "badconns", badconns);
+ add_error_variable(connptr, "denied", denied);
+ add_error_variable(connptr, "refused", refused);
+ add_standard_vars(connptr);
+ send_http_headers(connptr, 200, "Statistic requested");
+ send_html_file(statfile, connptr);
+ fclose(statfile);
+
+ return 0;
}
/*
@@ -120,26 +121,26 @@ showstats(struct conn_s *connptr)
int
update_stats(status_t update_level)
{
- switch (update_level) {
- case STAT_BADCONN:
- ++stats->num_badcons;
- break;
- case STAT_OPEN:
- ++stats->num_open;
- ++stats->num_reqs;
- break;
- case STAT_CLOSE:
- --stats->num_open;
- break;
- case STAT_REFUSE:
- ++stats->num_refused;
- break;
- case STAT_DENIED:
- ++stats->num_denied;
- break;
- default:
- return -1;
- }
-
- return 0;
+ switch (update_level) {
+ case STAT_BADCONN:
+ ++stats->num_badcons;
+ break;
+ case STAT_OPEN:
+ ++stats->num_open;
+ ++stats->num_reqs;
+ break;
+ case STAT_CLOSE:
+ --stats->num_open;
+ break;
+ case STAT_REFUSE:
+ ++stats->num_refused;
+ break;
+ case STAT_DENIED:
+ ++stats->num_denied;
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
}
diff --git a/src/stats.h b/src/stats.h
index 6d191f9..773f30a 100644
--- a/src/stats.h
+++ b/src/stats.h
@@ -1,4 +1,4 @@
-/* $Id: stats.h,v 1.5 2005-07-12 17:39:44 rjkaes Exp $
+/* $Id: stats.h,v 1.6 2005-08-15 03:54:31 rjkaes Exp $
*
* See 'stats.h' for a detailed description.
*
@@ -24,11 +24,11 @@
* Various logable statistics
*/
typedef enum {
- STAT_BADCONN, /* bad connection, for unknown reason */
- STAT_OPEN, /* connection opened */
- STAT_CLOSE, /* connection closed */
- STAT_REFUSE, /* connection refused (to outside world) */
- STAT_DENIED /* connection denied to tinyproxy itself */
+ STAT_BADCONN, /* bad connection, for unknown reason */
+ STAT_OPEN, /* connection opened */
+ STAT_CLOSE, /* connection closed */
+ STAT_REFUSE, /* connection refused (to outside world) */
+ STAT_DENIED /* connection denied to tinyproxy itself */
} status_t;
/*
diff --git a/src/text.c b/src/text.c
index 69d4a12..f520090 100644
--- a/src/text.c
+++ b/src/text.c
@@ -1,4 +1,4 @@
-/* $Id: text.c,v 1.4 2005-07-12 17:39:44 rjkaes Exp $
+/* $Id: text.c,v 1.5 2005-08-15 03:54:31 rjkaes Exp $
*
* The functions included here are useful for text manipulation. They
* replace or augment the standard C string library. These functions
@@ -31,16 +31,16 @@
size_t
strlcpy(char *dst, const char *src, size_t size)
{
- size_t len = strlen(src);
- size_t ret = len;
+ size_t len = strlen(src);
+ size_t ret = len;
- if (len >= size)
- len = size - 1;
+ if (len >= size)
+ len = size - 1;
- memcpy(dst, src, len);
- dst[len] = '\0';
+ memcpy(dst, src, len);
+ dst[len] = '\0';
- return ret;
+ return ret;
}
#endif
@@ -54,18 +54,18 @@ strlcpy(char *dst, const char *src, size_t size)
size_t
strlcat(char *dst, const char *src, size_t size)
{
- size_t len1 = strlen(dst);
- size_t len2 = strlen(src);
- size_t ret = len1 + len2;
-
- if (len1 + len2 >= size)
- len2 = size - len1 - 1;
- if (len2 > 0) {
- memcpy(dst + len1, src, len2);
- dst[len1 + len2] = '\0';
- }
-
- return ret;
+ size_t len1 = strlen(dst);
+ size_t len2 = strlen(src);
+ size_t ret = len1 + len2;
+
+ if (len1 + len2 >= size)
+ len2 = size - len1 - 1;
+ if (len2 > 0) {
+ memcpy(dst + len1, src, len2);
+ dst[len1 + len2] = '\0';
+ }
+
+ return ret;
}
#endif
@@ -81,25 +81,28 @@ strlcat(char *dst, const char *src, size_t size)
ssize_t
chomp(char *buffer, size_t length)
{
- size_t chars;
+ size_t chars;
- assert(buffer != NULL);
- assert(length > 0);
+ assert(buffer != NULL);
+ assert(length > 0);
- /* Make sure the arguments are valid */
- if (buffer == NULL) return -EFAULT;
- if (length < 1) return -ERANGE;
+ /* Make sure the arguments are valid */
+ if (buffer == NULL)
+ return -EFAULT;
+ if (length < 1)
+ return -ERANGE;
- chars = 0;
+ chars = 0;
- --length;
- while (buffer[length] == '\r' || buffer[length] == '\n') {
- buffer[length] = '\0';
- chars++;
+ --length;
+ while (buffer[length] == '\r' || buffer[length] == '\n') {
+ buffer[length] = '\0';
+ chars++;
- /* Stop once we get to zero to prevent wrap-around */
- if (length-- == 0) break;
- }
+ /* Stop once we get to zero to prevent wrap-around */
+ if (length-- == 0)
+ break;
+ }
- return chars;
+ return chars;
}
diff --git a/src/text.h b/src/text.h
index c8dd0aa..49e6492 100644
--- a/src/text.h
+++ b/src/text.h
@@ -1,4 +1,4 @@
-/* $Id: text.h,v 1.3 2005-07-12 17:39:44 rjkaes Exp $
+/* $Id: text.h,v 1.4 2005-08-15 03:54:31 rjkaes Exp $
*
* See 'text.c' for a detailed description.
*
@@ -20,11 +20,11 @@
#ifndef HAVE_STRLCAT
extern size_t strlcat(char *dst, const char *src, size_t size);
-#endif /* HAVE_STRLCAT */
+#endif /* HAVE_STRLCAT */
#ifndef HAVE_STRLCPY
extern size_t strlcpy(char *dst, const char *src, size_t size);
-#endif /* HAVE_STRLCPY */
+#endif /* HAVE_STRLCPY */
extern ssize_t chomp(char *buffer, size_t length);
diff --git a/src/tinyproxy.c b/src/tinyproxy.c
index d1f8777..1d4cff0 100644
--- a/src/tinyproxy.c
+++ b/src/tinyproxy.c
@@ -1,4 +1,4 @@
-/* $Id: tinyproxy.c,v 1.51 2005-07-12 17:39:44 rjkaes Exp $
+/* $Id: tinyproxy.c,v 1.52 2005-08-15 03:54:31 rjkaes Exp $
*
* The initialize routine. Basically sets up all the initial stuff (logfile,
* listening socket, config options, etc.) and then sits there and loops
@@ -44,8 +44,8 @@ RETSIGTYPE takesig(int sig);
*/
struct config_s config;
float load = 0.00;
-unsigned int received_sighup = FALSE; /* boolean */
-unsigned int processed_config_file = FALSE; /* boolean */
+unsigned int received_sighup = FALSE; /* boolean */
+unsigned int processed_config_file = FALSE; /* boolean */
/*
* Handle a signal
@@ -53,25 +53,24 @@ unsigned int processed_config_file = FALSE; /* boolean */
RETSIGTYPE
takesig(int sig)
{
- pid_t pid;
- int status;
+ pid_t pid;
+ int status;
- switch (sig) {
- case SIGHUP:
- received_sighup = TRUE;
- break;
+ switch (sig) {
+ case SIGHUP:
+ received_sighup = TRUE;
+ break;
- case SIGTERM:
- config.quit = TRUE;
- break;
+ case SIGTERM:
+ config.quit = TRUE;
+ break;
- case SIGCHLD:
- while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
- ;
- break;
- }
+ case SIGCHLD:
+ while ((pid = waitpid(-1, &status, WNOHANG)) > 0) ;
+ break;
+ }
- return;
+ return;
}
/*
@@ -80,7 +79,7 @@ takesig(int sig)
static void
display_version(void)
{
- printf("%s %s (%s)\n", PACKAGE, VERSION, TARGET_SYSTEM);
+ printf("%s %s (%s)\n", PACKAGE, VERSION, TARGET_SYSTEM);
}
/*
@@ -89,9 +88,9 @@ display_version(void)
static void
display_license(void)
{
- display_version();
+ display_version();
- printf("\
+ printf("\
Copyright 1998 Steven Young (sdyoung@well.com)\n\
Copyright 1998-2002 Robert James Kaes (rjkaes@users.sourceforge.net)\n\
Copyright 1999 George Talusan (gstalusan@uwaterloo.ca)\n\
@@ -118,8 +117,8 @@ display_license(void)
static void
display_usage(void)
{
- printf("Usage: %s [options]\n", PACKAGE);
- printf("\
+ printf("Usage: %s [options]\n", PACKAGE);
+ printf("\
Options:\n\
-d Operate in DEBUG mode.\n\
-c FILE Use an alternate configuration file.\n\
@@ -127,97 +126,97 @@ Options:\n\
-l Display the license.\n\
-v Display the version number.\n");
- /* Display the modes compiled into tinyproxy */
- printf("\nFeatures compiled in:\n");
+ /* Display the modes compiled into tinyproxy */
+ printf("\nFeatures compiled in:\n");
#ifdef XTINYPROXY_ENABLE
- printf(" XTinyproxy header\n");
-#endif /* XTINYPROXY */
+ printf(" XTinyproxy header\n");
+#endif /* XTINYPROXY */
#ifdef FILTER_ENABLE
- printf(" Filtering\n");
-#endif /* FILTER_ENABLE */
+ printf(" Filtering\n");
+#endif /* FILTER_ENABLE */
#ifndef NDEBUG
- printf(" Debugging code\n");
-#endif /* NDEBUG */
+ printf(" Debugging code\n");
+#endif /* NDEBUG */
#ifdef TRANSPARENT_PROXY
- printf(" Transparent proxy support\n");
+ printf(" Transparent proxy support\n");
#endif /* TRANSPARENT_PROXY */
#ifdef REVERSE_SUPPORT
- printf(" Reverse proxy support\n");
-#endif /* REVERSE_SUPPORT */
+ printf(" Reverse proxy support\n");
+#endif /* REVERSE_SUPPORT */
}
int
main(int argc, char **argv)
{
- int optch;
- unsigned int godaemon = TRUE; /* boolean */
- struct passwd *thisuser = NULL;
- struct group *thisgroup = NULL;
- FILE* config_file;
-
- /*
- * Disable the creation of CORE files right up front.
- */
+ int optch;
+ unsigned int godaemon = TRUE; /* boolean */
+ struct passwd *thisuser = NULL;
+ struct group *thisgroup = NULL;
+ FILE *config_file;
+
+ /*
+ * Disable the creation of CORE files right up front.
+ */
#if defined(HAVE_SETRLIMIT) && defined(NDEBUG)
- struct rlimit core_limit = { 0, 0 };
- if (setrlimit(RLIMIT_CORE, &core_limit) < 0) {
- fprintf(stderr, "%s: Could not set the core limit to zero.\n",
- argv[0]);
- exit(EX_SOFTWARE);
- }
-#endif /* HAVE_SETRLIMIT */
-
- /* Default configuration file location */
- config.config_file = DEFAULT_CONF_FILE;
-
- /*
- * Process the various options
- */
- while ((optch = getopt(argc, argv, "c:vldh")) != EOF) {
- switch (optch) {
- case 'v':
- display_version();
- exit(EX_OK);
- case 'l':
- display_license();
- exit(EX_OK);
- case 'd':
- godaemon = FALSE;
- break;
- case 'c':
- config.config_file = safestrdup(optarg);
- if (!config.config_file) {
- fprintf(stderr,
- "%s: Could not allocate memory.\n",
- argv[0]);
- exit(EX_SOFTWARE);
- }
- break;
- case 'h':
- default:
- display_usage();
- exit(EX_OK);
- }
- }
-
- log_message(LOG_INFO, "Initializing " PACKAGE " ...");
-
- /*
- * Make sure the HTML error pages array is NULL to begin with.
- * (FIXME: Should have a better API for all this)
- */
- config.errorpages = NULL;
-
- /*
- * Read in the settings from the config file.
- */
+ struct rlimit core_limit = { 0, 0 };
+ if (setrlimit(RLIMIT_CORE, &core_limit) < 0) {
+ fprintf(stderr, "%s: Could not set the core limit to zero.\n",
+ argv[0]);
+ exit(EX_SOFTWARE);
+ }
+#endif /* HAVE_SETRLIMIT */
+
+ /* Default configuration file location */
+ config.config_file = DEFAULT_CONF_FILE;
+
+ /*
+ * Process the various options
+ */
+ while ((optch = getopt(argc, argv, "c:vldh")) != EOF) {
+ switch (optch) {
+ case 'v':
+ display_version();
+ exit(EX_OK);
+ case 'l':
+ display_license();
+ exit(EX_OK);
+ case 'd':
+ godaemon = FALSE;
+ break;
+ case 'c':
+ config.config_file = safestrdup(optarg);
+ if (!config.config_file) {
+ fprintf(stderr,
+ "%s: Could not allocate memory.\n",
+ argv[0]);
+ exit(EX_SOFTWARE);
+ }
+ break;
+ case 'h':
+ default:
+ display_usage();
+ exit(EX_OK);
+ }
+ }
+
+ log_message(LOG_INFO, "Initializing " PACKAGE " ...");
+
+ /*
+ * Make sure the HTML error pages array is NULL to begin with.
+ * (FIXME: Should have a better API for all this)
+ */
+ config.errorpages = NULL;
+
+ /*
+ * Read in the settings from the config file.
+ */
config_file = fopen(config.config_file, "r");
if (!config_file) {
- fprintf(stderr,
- "%s: Could not open configuration file \"%s\".\n",
- argv[0], config.config_file);
- exit(EX_SOFTWARE);
- }
+ fprintf(stderr,
+ "%s: Could not open configuration file \"%s\".\n",
+ argv[0], config.config_file);
+ exit(EX_SOFTWARE);
+ }
if (config_compile() || config_parse(&config, config_file)) {
fprintf(stderr,
"Unable to parse configuration file. Not starting.\n");
@@ -232,194 +231,192 @@ main(int argc, char **argv)
if (config.logf_name) {
if (open_log_file(config.logf_name) < 0) {
fprintf(stderr,
- "%s: Could not create log file.\n",
- argv[0]);
+ "%s: Could not create log file.\n", argv[0]);
exit(EX_SOFTWARE);
}
- config.syslog = FALSE; /* disable syslog */
+ config.syslog = FALSE; /* disable syslog */
} else if (config.syslog) {
- if (godaemon == TRUE)
- openlog("tinyproxy", LOG_PID, LOG_DAEMON);
- else
- openlog("tinyproxy", LOG_PID, LOG_USER);
- } else {
+ if (godaemon == TRUE)
+ openlog("tinyproxy", LOG_PID, LOG_DAEMON);
+ else
+ openlog("tinyproxy", LOG_PID, LOG_USER);
+ } else {
fprintf(stderr,
"%s: Either define a logfile or enable syslog logging\n",
argv[0]);
exit(EX_SOFTWARE);
}
- processed_config_file = TRUE;
- send_stored_logs();
-
- /*
- * Set the default values if they were not set in the config file.
- */
- if (config.port == 0) {
- fprintf(stderr,
- "%s: You MUST set a Port in the configuration file.\n",
- argv[0]);
- exit(EX_SOFTWARE);
- }
- if (!config.stathost) {
- log_message(LOG_INFO, "Setting stathost to \"%s\".",
- DEFAULT_STATHOST);
- config.stathost = DEFAULT_STATHOST;
- }
- if (!config.username) {
- log_message(LOG_WARNING,
- "You SHOULD set a UserName in the configuration file. Using current user instead.");
- }
- if (config.idletimeout == 0) {
- log_message(LOG_WARNING, "Invalid idle time setting. Only values greater than zero allowed; therefore setting idle timeout to %u seconds.",
- MAX_IDLE_TIME);
- config.idletimeout = MAX_IDLE_TIME;
- }
-
- init_stats();
-
- /*
- * If ANONYMOUS is turned on, make sure that Content-Length is
- * in the list of allowed headers, since it is required in a
- * HTTP/1.0 request. Also add the Content-Type header since it goes
- * hand in hand with Content-Length.
- * - rjkaes
- */
- if (is_anonymous_enabled()) {
- anonymous_insert("Content-Length");
- anonymous_insert("Content-Type");
- }
-
- if (godaemon == TRUE)
- makedaemon();
-
- if (config.pidpath) {
- if (pidfile_create(config.pidpath) < 0) {
- fprintf(stderr, "%s: Could not create PID file.\n",
- argv[0]);
- exit(EX_OSERR);
- }
- }
-
- if (set_signal_handler(SIGPIPE, SIG_IGN) == SIG_ERR) {
- fprintf(stderr, "%s: Could not set the \"SIGPIPE\" signal.\n",
- argv[0]);
- exit(EX_OSERR);
- }
+ processed_config_file = TRUE;
+ send_stored_logs();
+
+ /*
+ * Set the default values if they were not set in the config file.
+ */
+ if (config.port == 0) {
+ fprintf(stderr,
+ "%s: You MUST set a Port in the configuration file.\n",
+ argv[0]);
+ exit(EX_SOFTWARE);
+ }
+ if (!config.stathost) {
+ log_message(LOG_INFO, "Setting stathost to \"%s\".",
+ DEFAULT_STATHOST);
+ config.stathost = DEFAULT_STATHOST;
+ }
+ if (!config.username) {
+ log_message(LOG_WARNING,
+ "You SHOULD set a UserName in the configuration file. Using current user instead.");
+ }
+ if (config.idletimeout == 0) {
+ log_message(LOG_WARNING,
+ "Invalid idle time setting. Only values greater than zero allowed; therefore setting idle timeout to %u seconds.",
+ MAX_IDLE_TIME);
+ config.idletimeout = MAX_IDLE_TIME;
+ }
+
+ init_stats();
+
+ /*
+ * If ANONYMOUS is turned on, make sure that Content-Length is
+ * in the list of allowed headers, since it is required in a
+ * HTTP/1.0 request. Also add the Content-Type header since it goes
+ * hand in hand with Content-Length.
+ * - rjkaes
+ */
+ if (is_anonymous_enabled()) {
+ anonymous_insert("Content-Length");
+ anonymous_insert("Content-Type");
+ }
+
+ if (godaemon == TRUE)
+ makedaemon();
+ if (config.pidpath) {
+ if (pidfile_create(config.pidpath) < 0) {
+ fprintf(stderr, "%s: Could not create PID file.\n",
+ argv[0]);
+ exit(EX_OSERR);
+ }
+ }
+
+ if (set_signal_handler(SIGPIPE, SIG_IGN) == SIG_ERR) {
+ fprintf(stderr, "%s: Could not set the \"SIGPIPE\" signal.\n",
+ argv[0]);
+ exit(EX_OSERR);
+ }
#ifdef FILTER_ENABLE
- if (config.filter)
- filter_init();
-#endif /* FILTER_ENABLE */
-
- /*
- * Start listening on the selected port.
- */
- if (child_listening_sock(config.port) < 0) {
- fprintf(stderr, "%s: Could not create listening socket.\n",
- argv[0]);
- exit(EX_OSERR);
- }
-
- /*
- * Switch to a different user.
- */
- if (geteuid() == 0) {
- if (config.group && strlen(config.group) > 0) {
- thisgroup = getgrnam(config.group);
- if (!thisgroup) {
- fprintf(stderr,
- "%s: Unable to find group \"%s\".\n",
- argv[0], config.group);
- exit(EX_NOUSER);
- }
- if (setgid(thisgroup->gr_gid) < 0) {
- fprintf(stderr,
- "%s: Unable to change to group \"%s\".\n",
- argv[0], config.group);
- exit(EX_CANTCREAT);
- }
- log_message(LOG_INFO, "Now running as group \"%s\".",
- config.group);
- }
- if (config.username && strlen(config.username) > 0) {
- thisuser = getpwnam(config.username);
- if (!thisuser) {
- fprintf(stderr,
- "%s: Unable to find user \"%s\".",
- argv[0], config.username);
- exit(EX_NOUSER);
- }
- if (setuid(thisuser->pw_uid) < 0) {
- fprintf(stderr,
- "%s: Unable to change to user \"%s\".",
- argv[0], config.username);
- exit(EX_CANTCREAT);
- }
- log_message(LOG_INFO, "Now running as user \"%s\".",
- config.username);
- }
- } else {
- log_message(LOG_WARNING,
- "Not running as root, so not changing UID/GID.");
- }
-
- if (child_pool_create() < 0) {
- fprintf(stderr, "%s: Could not create the pool of children.",
- argv[0]);
- exit(EX_SOFTWARE);
- }
-
- /*
- * These signals are only for the parent process.
- */
- log_message(LOG_INFO, "Setting the various signals.");
- if (set_signal_handler(SIGCHLD, takesig) == SIG_ERR) {
- fprintf(stderr, "%s: Could not set the \"SIGCHLD\" signal.\n",
- argv[0]);
- exit(EX_OSERR);
- }
- if (set_signal_handler(SIGTERM, takesig) == SIG_ERR) {
- fprintf(stderr, "%s: Could not set the \"SIGTERM\" signal.\n",
- argv[0]);
- exit(EX_OSERR);
- }
- if (set_signal_handler(SIGHUP, takesig) == SIG_ERR) {
- fprintf(stderr, "%s: Could not set the \"SIGHUP\" signal.\n",
- argv[0]);
- exit(EX_OSERR);
- }
-
- /*
- * Start the main loop.
- */
- log_message(LOG_INFO, "Starting main loop. Accepting connections.");
-
- child_main_loop();
-
- log_message(LOG_INFO, "Shutting down.");
-
- child_kill_children();
- child_close_sock();
-
- /*
- * Remove the PID file.
- */
- if (unlink(config.pidpath) < 0) {
- log_message(LOG_WARNING,
- "Could not remove PID file \"%s\": %s.",
- config.pidpath, strerror(errno));
- }
+ if (config.filter)
+ filter_init();
+#endif /* FILTER_ENABLE */
+
+ /*
+ * Start listening on the selected port.
+ */
+ if (child_listening_sock(config.port) < 0) {
+ fprintf(stderr, "%s: Could not create listening socket.\n",
+ argv[0]);
+ exit(EX_OSERR);
+ }
+
+ /*
+ * Switch to a different user.
+ */
+ if (geteuid() == 0) {
+ if (config.group && strlen(config.group) > 0) {
+ thisgroup = getgrnam(config.group);
+ if (!thisgroup) {
+ fprintf(stderr,
+ "%s: Unable to find group \"%s\".\n",
+ argv[0], config.group);
+ exit(EX_NOUSER);
+ }
+ if (setgid(thisgroup->gr_gid) < 0) {
+ fprintf(stderr,
+ "%s: Unable to change to group \"%s\".\n",
+ argv[0], config.group);
+ exit(EX_CANTCREAT);
+ }
+ log_message(LOG_INFO, "Now running as group \"%s\".",
+ config.group);
+ }
+ if (config.username && strlen(config.username) > 0) {
+ thisuser = getpwnam(config.username);
+ if (!thisuser) {
+ fprintf(stderr,
+ "%s: Unable to find user \"%s\".",
+ argv[0], config.username);
+ exit(EX_NOUSER);
+ }
+ if (setuid(thisuser->pw_uid) < 0) {
+ fprintf(stderr,
+ "%s: Unable to change to user \"%s\".",
+ argv[0], config.username);
+ exit(EX_CANTCREAT);
+ }
+ log_message(LOG_INFO, "Now running as user \"%s\".",
+ config.username);
+ }
+ } else {
+ log_message(LOG_WARNING,
+ "Not running as root, so not changing UID/GID.");
+ }
+ if (child_pool_create() < 0) {
+ fprintf(stderr, "%s: Could not create the pool of children.",
+ argv[0]);
+ exit(EX_SOFTWARE);
+ }
+
+ /*
+ * These signals are only for the parent process.
+ */
+ log_message(LOG_INFO, "Setting the various signals.");
+ if (set_signal_handler(SIGCHLD, takesig) == SIG_ERR) {
+ fprintf(stderr, "%s: Could not set the \"SIGCHLD\" signal.\n",
+ argv[0]);
+ exit(EX_OSERR);
+ }
+ if (set_signal_handler(SIGTERM, takesig) == SIG_ERR) {
+ fprintf(stderr, "%s: Could not set the \"SIGTERM\" signal.\n",
+ argv[0]);
+ exit(EX_OSERR);
+ }
+ if (set_signal_handler(SIGHUP, takesig) == SIG_ERR) {
+ fprintf(stderr, "%s: Could not set the \"SIGHUP\" signal.\n",
+ argv[0]);
+ exit(EX_OSERR);
+ }
+
+ /*
+ * Start the main loop.
+ */
+ log_message(LOG_INFO, "Starting main loop. Accepting connections.");
+
+ child_main_loop();
+
+ log_message(LOG_INFO, "Shutting down.");
+
+ child_kill_children();
+ child_close_sock();
+
+ /*
+ * Remove the PID file.
+ */
+ if (unlink(config.pidpath) < 0) {
+ log_message(LOG_WARNING,
+ "Could not remove PID file \"%s\": %s.",
+ config.pidpath, strerror(errno));
+ }
#ifdef FILTER_ENABLE
- if (config.filter)
- filter_destroy();
-#endif /* FILTER_ENABLE */
+ if (config.filter)
+ filter_destroy();
+#endif /* FILTER_ENABLE */
- if (config.syslog)
- closelog();
- else
- close_log_file();
+ if (config.syslog)
+ closelog();
+ else
+ close_log_file();
- exit(EX_OK);
+ exit(EX_OK);
}
diff --git a/src/tinyproxy.h b/src/tinyproxy.h
index f967b36..4cb091c 100644
--- a/src/tinyproxy.h
+++ b/src/tinyproxy.h
@@ -1,4 +1,4 @@
-/* $Id: tinyproxy.h,v 1.46 2005-07-12 17:39:44 rjkaes Exp $
+/* $Id: tinyproxy.h,v 1.47 2005-08-15 03:54:31 rjkaes Exp $
*
* See 'tinyproxy.c' for a detailed description.
*
@@ -23,26 +23,26 @@
#include "hashmap.h"
/* Global variables for the main controls of the program */
-#define MAXBUFFSIZE ((size_t)(1024 * 96)) /* Max size of buffer */
-#define MAX_IDLE_TIME (60 * 10) /* 10 minutes of no activity */
+#define MAXBUFFSIZE ((size_t)(1024 * 96)) /* Max size of buffer */
+#define MAX_IDLE_TIME (60 * 10) /* 10 minutes of no activity */
/*
* Even if upstream support is not compiled into tinyproxy, this
* structure still needs to be defined.
*/
struct upstream {
- struct upstream *next;
- char *domain; /* optional */
- char *host;
- int port;
- in_addr_t ip, mask;
+ struct upstream *next;
+ char *domain; /* optional */
+ char *host;
+ int port;
+ in_addr_t ip, mask;
};
#ifdef REVERSE_SUPPORT
struct reversepath {
- struct reversepath *next;
- char *path;
- char *url;
+ struct reversepath *next;
+ char *path;
+ char *url;
};
#define REVERSE_COOKIE "yummy_magical_cookie"
@@ -52,63 +52,63 @@ struct reversepath {
* Hold all the configuration time information.
*/
struct config_s {
- char *logf_name;
- char *config_file;
- unsigned int syslog; /* boolean */
- int port;
- char *stathost;
- unsigned int quit; /* boolean */
- char *username;
- char *group;
- char *ipAddr;
+ char *logf_name;
+ char *config_file;
+ unsigned int syslog; /* boolean */
+ int port;
+ char *stathost;
+ unsigned int quit; /* boolean */
+ char *username;
+ char *group;
+ char *ipAddr;
#ifdef FILTER_ENABLE
- char *filter;
- unsigned int filter_url; /* boolean */
- unsigned int filter_extended; /* boolean */
- unsigned int filter_casesensitive; /* boolean */
-#endif /* FILTER_ENABLE */
+ char *filter;
+ unsigned int filter_url; /* boolean */
+ unsigned int filter_extended; /* boolean */
+ unsigned int filter_casesensitive; /* boolean */
+#endif /* FILTER_ENABLE */
#ifdef XTINYPROXY_ENABLE
- char *my_domain;
+ char *my_domain;
#endif
#ifdef REVERSE_SUPPORT
- struct reversepath *reversepath_list;
- unsigned int reverseonly; /* boolean */
- unsigned int reversemagic; /* boolean */
- char *reversebaseurl;
+ struct reversepath *reversepath_list;
+ unsigned int reverseonly; /* boolean */
+ unsigned int reversemagic; /* boolean */
+ char *reversebaseurl;
#endif
#ifdef UPSTREAM_SUPPORT
- struct upstream *upstream_list;
-#endif /* UPSTREAM_SUPPORT */
- char *pidpath;
- unsigned int idletimeout;
- char* bind_address;
- unsigned int bindsame;
+ struct upstream *upstream_list;
+#endif /* UPSTREAM_SUPPORT */
+ char *pidpath;
+ unsigned int idletimeout;
+ char *bind_address;
+ unsigned int bindsame;
- /*
- * The configured name to use in the HTTP "Via" header field.
- */
- char* via_proxy_name;
+ /*
+ * The configured name to use in the HTTP "Via" header field.
+ */
+ char *via_proxy_name;
/*
- * Error page support. Map error numbers to file paths.
- */
- hashmap_t errorpages;
+ * Error page support. Map error numbers to file paths.
+ */
+ hashmap_t errorpages;
- /*
- * Error page to be displayed if appropriate page cannot be located
- * in the errorpages structure.
- */
- char *errorpage_undef;
+ /*
+ * Error page to be displayed if appropriate page cannot be located
+ * in the errorpages structure.
+ */
+ char *errorpage_undef;
- /*
- * The HTML statistics page.
- */
- char *statpage;
+ /*
+ * The HTML statistics page.
+ */
+ char *statpage;
};
/* Global Structures used in the program */
extern struct config_s config;
-extern unsigned int received_sighup; /* boolean */
-extern unsigned int processed_config_file; /* boolean */
+extern unsigned int received_sighup; /* boolean */
+extern unsigned int processed_config_file; /* boolean */
#endif
diff --git a/src/utils.c b/src/utils.c
index 167d9e3..7201e9e 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -1,4 +1,4 @@
-/* $Id: utils.c,v 1.39 2005-07-12 17:39:44 rjkaes Exp $
+/* $Id: utils.c,v 1.40 2005-08-15 03:54:31 rjkaes Exp $
*
* Misc. routines which are used by the various functions to handle strings
* and memory allocation and pretty much anything else we can think of. Also,
@@ -31,26 +31,26 @@
*/
int
send_http_message(struct conn_s *connptr, int http_code,
- const char *error_title, const char *message)
+ const char *error_title, const char *message)
{
- static char* headers[] = {
- "Server: " PACKAGE "/" VERSION,
- "Content-type: text/html",
- "Connection: close"
- };
+ static char *headers[] = {
+ "Server: " PACKAGE "/" VERSION,
+ "Content-type: text/html",
+ "Connection: close"
+ };
- http_message_t msg;
+ http_message_t msg;
- msg = http_message_create(http_code, error_title);
- if (msg == NULL)
- return -1;
+ msg = http_message_create(http_code, error_title);
+ if (msg == NULL)
+ return -1;
- http_message_add_headers(msg, headers, 3);
- http_message_set_body(msg, message, strlen(message));
- http_message_send(msg, connptr->client_fd);
- http_message_destroy(msg);
+ http_message_add_headers(msg, headers, 3);
+ http_message_set_body(msg, message, strlen(message));
+ http_message_send(msg, connptr->client_fd);
+ http_message_destroy(msg);
- return 0;
+ return 0;
}
/*
@@ -59,116 +59,116 @@ send_http_message(struct conn_s *connptr, int http_code,
int
create_file_safely(const char *filename, unsigned int truncate_file)
{
- struct stat lstatinfo;
- int fildes;
-
- /*
- * lstat() the file. If it doesn't exist, create it with O_EXCL.
- * If it does exist, open it for writing and perform the fstat()
- * check.
- */
- if (lstat(filename, &lstatinfo) < 0) {
- /*
- * If lstat() failed for any reason other than "file not
- * existing", exit.
- */
- if (errno != ENOENT) {
- fprintf(stderr,
- "%s: Error checking file %s: %s\n",
- PACKAGE, filename, strerror(errno));
- return -EACCES;
- }
-
- /*
- * The file doesn't exist, so create it with O_EXCL to make
- * sure an attacker can't slip in a file between the lstat()
- * and open()
- */
- if ((fildes =
- open(filename, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0) {
- fprintf(stderr,
- "%s: Could not create file %s: %s\n",
- PACKAGE, filename, strerror(errno));
- return fildes;
- }
- } else {
- struct stat fstatinfo;
- int flags;
-
- flags = O_RDWR;
- if (!truncate_file)
- flags |= O_APPEND;
-
- /*
- * Open an existing file.
- */
- if ((fildes = open(filename, flags)) < 0) {
- fprintf(stderr,
- "%s: Could not open file %s: %s\n",
- PACKAGE, filename, strerror(errno));
- return fildes;
- }
-
- /*
- * fstat() the opened file and check that the file mode bits,
- * inode, and device match.
- */
- if (fstat(fildes, &fstatinfo) < 0
- || lstatinfo.st_mode != fstatinfo.st_mode
- || lstatinfo.st_ino != fstatinfo.st_ino
- || lstatinfo.st_dev != fstatinfo.st_dev) {
- fprintf(stderr,
- "%s: The file %s has been changed before it could be opened\n",
- PACKAGE, filename);
- close(fildes);
- return -EIO;
- }
-
- /*
- * If the above check was passed, we know that the lstat()
- * and fstat() were done on the same file. Now we check that
- * there's only one link, and that it's a normal file (this
- * isn't strictly necessary because the fstat() vs lstat()
- * st_mode check would also find this)
- */
- if (fstatinfo.st_nlink > 1 || !S_ISREG(lstatinfo.st_mode)) {
- fprintf(stderr,
- "%s: The file %s has too many links, or is not a regular file: %s\n",
- PACKAGE, filename, strerror(errno));
- close(fildes);
- return -EMLINK;
- }
-
- /*
- * Just return the file descriptor if we _don't_ want the file
- * truncated.
- */
- if (!truncate_file)
- return fildes;
-
- /*
- * On systems which don't support ftruncate() the best we can
- * do is to close the file and reopen it in create mode, which
- * unfortunately leads to a race condition, however "systems
- * which don't support ftruncate()" is pretty much SCO only,
- * and if you're using that you deserve what you get.
- * ("Little sympathy has been extended")
- */
+ struct stat lstatinfo;
+ int fildes;
+
+ /*
+ * lstat() the file. If it doesn't exist, create it with O_EXCL.
+ * If it does exist, open it for writing and perform the fstat()
+ * check.
+ */
+ if (lstat(filename, &lstatinfo) < 0) {
+ /*
+ * If lstat() failed for any reason other than "file not
+ * existing", exit.
+ */
+ if (errno != ENOENT) {
+ fprintf(stderr,
+ "%s: Error checking file %s: %s\n",
+ PACKAGE, filename, strerror(errno));
+ return -EACCES;
+ }
+
+ /*
+ * The file doesn't exist, so create it with O_EXCL to make
+ * sure an attacker can't slip in a file between the lstat()
+ * and open()
+ */
+ if ((fildes =
+ open(filename, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0) {
+ fprintf(stderr,
+ "%s: Could not create file %s: %s\n",
+ PACKAGE, filename, strerror(errno));
+ return fildes;
+ }
+ } else {
+ struct stat fstatinfo;
+ int flags;
+
+ flags = O_RDWR;
+ if (!truncate_file)
+ flags |= O_APPEND;
+
+ /*
+ * Open an existing file.
+ */
+ if ((fildes = open(filename, flags)) < 0) {
+ fprintf(stderr,
+ "%s: Could not open file %s: %s\n",
+ PACKAGE, filename, strerror(errno));
+ return fildes;
+ }
+
+ /*
+ * fstat() the opened file and check that the file mode bits,
+ * inode, and device match.
+ */
+ if (fstat(fildes, &fstatinfo) < 0
+ || lstatinfo.st_mode != fstatinfo.st_mode
+ || lstatinfo.st_ino != fstatinfo.st_ino
+ || lstatinfo.st_dev != fstatinfo.st_dev) {
+ fprintf(stderr,
+ "%s: The file %s has been changed before it could be opened\n",
+ PACKAGE, filename);
+ close(fildes);
+ return -EIO;
+ }
+
+ /*
+ * If the above check was passed, we know that the lstat()
+ * and fstat() were done on the same file. Now we check that
+ * there's only one link, and that it's a normal file (this
+ * isn't strictly necessary because the fstat() vs lstat()
+ * st_mode check would also find this)
+ */
+ if (fstatinfo.st_nlink > 1 || !S_ISREG(lstatinfo.st_mode)) {
+ fprintf(stderr,
+ "%s: The file %s has too many links, or is not a regular file: %s\n",
+ PACKAGE, filename, strerror(errno));
+ close(fildes);
+ return -EMLINK;
+ }
+
+ /*
+ * Just return the file descriptor if we _don't_ want the file
+ * truncated.
+ */
+ if (!truncate_file)
+ return fildes;
+
+ /*
+ * On systems which don't support ftruncate() the best we can
+ * do is to close the file and reopen it in create mode, which
+ * unfortunately leads to a race condition, however "systems
+ * which don't support ftruncate()" is pretty much SCO only,
+ * and if you're using that you deserve what you get.
+ * ("Little sympathy has been extended")
+ */
#ifdef HAVE_FTRUNCATE
- ftruncate(fildes, 0);
+ ftruncate(fildes, 0);
#else
- close(fildes);
- if ((fildes =
- open(filename, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) {
- fprintf(stderr,
- "%s: Could not open file %s: %s.",
- PACKAGE, filename, strerror(errno));
- return fildes;
- }
-#endif /* HAVE_FTRUNCATE */
- }
-
- return fildes;
+ close(fildes);
+ if ((fildes =
+ open(filename, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) {
+ fprintf(stderr,
+ "%s: Could not open file %s: %s.",
+ PACKAGE, filename, strerror(errno));
+ return fildes;
+ }
+#endif /* HAVE_FTRUNCATE */
+ }
+
+ return fildes;
}
/*
@@ -177,28 +177,28 @@ create_file_safely(const char *filename, unsigned int truncate_file)
int
pidfile_create(const char *filename)
{
- int fildes;
- FILE *fd;
-
- /*
- * Create a new file
- */
- if ((fildes = create_file_safely(filename, TRUE)) < 0)
- return fildes;
-
- /*
- * Open a stdio file over the low-level one.
- */
- if ((fd = fdopen(fildes, "w")) == NULL) {
- fprintf(stderr,
- "%s: Could not write PID file %s: %s.",
- PACKAGE, filename, strerror(errno));
- close(fildes);
- unlink(filename);
- return -EIO;
- }
-
- fprintf(fd, "%ld\n", (long) getpid());
- fclose(fd);
- return 0;
+ int fildes;
+ FILE *fd;
+
+ /*
+ * Create a new file
+ */
+ if ((fildes = create_file_safely(filename, TRUE)) < 0)
+ return fildes;
+
+ /*
+ * Open a stdio file over the low-level one.
+ */
+ if ((fd = fdopen(fildes, "w")) == NULL) {
+ fprintf(stderr,
+ "%s: Could not write PID file %s: %s.",
+ PACKAGE, filename, strerror(errno));
+ close(fildes);
+ unlink(filename);
+ return -EIO;
+ }
+
+ fprintf(fd, "%ld\n", (long)getpid());
+ fclose(fd);
+ return 0;
}
diff --git a/src/utils.h b/src/utils.h
index 86bd617..395c46e 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -1,4 +1,4 @@
-/* $Id: utils.h,v 1.24 2005-07-12 17:39:44 rjkaes Exp $
+/* $Id: utils.h,v 1.25 2005-08-15 03:54:31 rjkaes Exp $
*
* See 'utils.h' for a detailed description.
*
@@ -25,7 +25,7 @@
struct conn_s;
extern int send_http_message(struct conn_s *connptr, int http_code,
- const char *error_title, const char *message);
+ const char *error_title, const char *message);
extern int pidfile_create(const char *path);
extern int create_file_safely(const char *filename, unsigned int truncate_file);
diff --git a/src/vector.c b/src/vector.c
index b938fc5..984198f 100644
--- a/src/vector.c
+++ b/src/vector.c
@@ -1,4 +1,4 @@
-/* $Id: vector.c,v 1.12 2005-07-12 17:39:44 rjkaes Exp $
+/* $Id: vector.c,v 1.13 2005-08-15 03:54:31 rjkaes Exp $
*
* A vector implementation. The vector can be of an arbitrary length, and
* the data for each entry is an lump of data (the size is stored in the
@@ -34,16 +34,16 @@
* count of the number of entries (or how long the vector is.)
*/
struct vectorentry_s {
- void *data;
- size_t len;
+ void *data;
+ size_t len;
- struct vectorentry_s *next;
+ struct vectorentry_s *next;
};
struct vector_s {
- size_t num_entries;
- struct vectorentry_s *head;
- struct vectorentry_s *tail;
+ size_t num_entries;
+ struct vectorentry_s *head;
+ struct vectorentry_s *tail;
};
/*
@@ -56,16 +56,16 @@ struct vector_s {
vector_t
vector_create(void)
{
- vector_t vector;
+ vector_t vector;
- vector = safemalloc(sizeof(struct vector_s));
- if (!vector)
- return NULL;
+ vector = safemalloc(sizeof(struct vector_s));
+ if (!vector)
+ return NULL;
- vector->num_entries = 0;
- vector->head = vector->tail = NULL;
-
- return vector;
+ vector->num_entries = 0;
+ vector->head = vector->tail = NULL;
+
+ return vector;
}
/*
@@ -77,23 +77,23 @@ vector_create(void)
int
vector_delete(vector_t vector)
{
- struct vectorentry_s *ptr, *next;
+ struct vectorentry_s *ptr, *next;
+
+ if (!vector)
+ return -EINVAL;
- if (!vector)
- return -EINVAL;
-
- ptr = vector->head;
- while (ptr) {
- next = ptr->next;
- safefree(ptr->data);
- safefree(ptr);
+ ptr = vector->head;
+ while (ptr) {
+ next = ptr->next;
+ safefree(ptr->data);
+ safefree(ptr);
- ptr = next;
- }
+ ptr = next;
+ }
- safefree(vector);
+ safefree(vector);
- return 0;
+ return 0;
}
/*
@@ -112,42 +112,42 @@ vector_delete(vector_t vector)
static int
vector_insert(vector_t vector, void *data, ssize_t len, int pos)
{
- struct vectorentry_s *entry;
-
- if (!vector || !data || len <= 0 ||
- (pos != INSERT_PREPEND && pos != INSERT_APPEND))
- return -EINVAL;
-
- entry = safemalloc(sizeof(struct vectorentry_s));
- if (!entry)
- return -ENOMEM;
-
- entry->data = safemalloc(len);
- if (!entry->data) {
- safefree(entry);
- return -ENOMEM;
- }
-
- memcpy(entry->data, data, len);
- entry->len = len;
- entry->next = NULL;
-
- /* If there is no head or tail, create them */
- if (!vector->head && !vector->tail)
- vector->head = vector->tail = entry;
- else if (pos == 0) {
- /* prepend the entry */
- entry->next = vector->head;
- vector->head = entry;
- } else {
- /* append the entry */
- vector->tail->next = entry;
- vector->tail = entry;
- }
-
- vector->num_entries++;
-
- return 0;
+ struct vectorentry_s *entry;
+
+ if (!vector || !data || len <= 0 ||
+ (pos != INSERT_PREPEND && pos != INSERT_APPEND))
+ return -EINVAL;
+
+ entry = safemalloc(sizeof(struct vectorentry_s));
+ if (!entry)
+ return -ENOMEM;
+
+ entry->data = safemalloc(len);
+ if (!entry->data) {
+ safefree(entry);
+ return -ENOMEM;
+ }
+
+ memcpy(entry->data, data, len);
+ entry->len = len;
+ entry->next = NULL;
+
+ /* If there is no head or tail, create them */
+ if (!vector->head && !vector->tail)
+ vector->head = vector->tail = entry;
+ else if (pos == 0) {
+ /* prepend the entry */
+ entry->next = vector->head;
+ vector->head = entry;
+ } else {
+ /* append the entry */
+ vector->tail->next = entry;
+ vector->tail = entry;
+ }
+
+ vector->num_entries++;
+
+ return 0;
}
/*
@@ -158,13 +158,13 @@ vector_insert(vector_t vector, void *data, ssize_t len, int pos)
int
vector_append(vector_t vector, void *data, ssize_t len)
{
- return vector_insert(vector, data, len, INSERT_APPEND);
+ return vector_insert(vector, data, len, INSERT_APPEND);
}
int
vector_prepend(vector_t vector, void *data, ssize_t len)
{
- return vector_insert(vector, data, len, INSERT_PREPEND);
+ return vector_insert(vector, data, len, INSERT_PREPEND);
}
/*
@@ -175,26 +175,26 @@ vector_prepend(vector_t vector, void *data, ssize_t len)
* length of data if position is valid
*/
void *
-vector_getentry(vector_t vector, size_t pos, size_t* size)
+vector_getentry(vector_t vector, size_t pos, size_t * size)
{
- struct vectorentry_s *ptr;
- size_t loc;
+ struct vectorentry_s *ptr;
+ size_t loc;
- if (!vector || pos < 0 || pos >= vector->num_entries)
- return NULL;
+ if (!vector || pos < 0 || pos >= vector->num_entries)
+ return NULL;
- loc = 0;
- ptr = vector->head;
+ loc = 0;
+ ptr = vector->head;
- while (loc != pos) {
- ptr = ptr->next;
- loc++;
- }
+ while (loc != pos) {
+ ptr = ptr->next;
+ loc++;
+ }
- if (size)
- *size = ptr->len;
+ if (size)
+ *size = ptr->len;
- return ptr->data;
+ return ptr->data;
}
/*
@@ -206,8 +206,8 @@ vector_getentry(vector_t vector, size_t pos, size_t* size)
ssize_t
vector_length(vector_t vector)
{
- if (!vector)
- return -EINVAL;
+ if (!vector)
+ return -EINVAL;
- return vector->num_entries;
+ return vector->num_entries;
}
diff --git a/src/vector.h b/src/vector.h
index 3c8e8bb..3db694d 100644
--- a/src/vector.h
+++ b/src/vector.h
@@ -1,4 +1,4 @@
-/* $Id: vector.h,v 1.6 2005-07-12 17:39:44 rjkaes Exp $
+/* $Id: vector.h,v 1.7 2005-08-15 03:54:31 rjkaes Exp $
*
* A vector implementation. The vector can be of an arbritrary length, and
* the data for each entry is an lump of data (the size is stored in the
@@ -34,14 +34,14 @@ extern "C" {
* vector. Sure, it's a pointer, but the struct is hidden in the C file.
* So, just use the vector_t like it's a cookie. :)
*/
-typedef struct vector_s *vector_t;
+ typedef struct vector_s *vector_t;
/*
* vector_create() takes no arguments.
* vector_delete() is self explanatory.
*/
-extern vector_t vector_create(void);
-extern int vector_delete(vector_t vector);
+ extern vector_t vector_create(void);
+ extern int vector_delete(vector_t vector);
/*
* When you insert a piece of data into the vector, the data will be
@@ -51,8 +51,8 @@ extern int vector_delete(vector_t vector);
* Returns: negative on error
* 0 upon successful insert.
*/
-extern int vector_append(vector_t vector, void *data, ssize_t len);
-extern int vector_prepend(vector_t vector, void *data, ssize_t len);
+ extern int vector_append(vector_t vector, void *data, ssize_t len);
+ extern int vector_prepend(vector_t vector, void *data, ssize_t len);
/*
* A pointer to the data at position "pos" (zero based) is returned and the
@@ -70,7 +70,8 @@ extern int vector_prepend(vector_t vector, void *data, ssize_t len);
* Returns: NULL on error
* valid pointer to data
*/
-extern void* vector_getentry(vector_t vector, size_t pos, size_t* size);
+ extern void *vector_getentry(vector_t vector, size_t pos,
+ size_t * size);
/*
* Returns the number of enteries (or the length) of the vector.
@@ -78,10 +79,9 @@ extern void* vector_getentry(vector_t vector, size_t pos, size_t* size);
* Returns: negative if vector is not valid
* positive length of vector otherwise
*/
-extern ssize_t vector_length(vector_t vector);
+ extern ssize_t vector_length(vector_t vector);
#if defined(__cplusplus)
}
-#endif /* C++ */
-
-#endif /* _VECTOR_H */
+#endif /* C++ */
+#endif /* _VECTOR_H */