summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/acl.c503
-rw-r--r--src/acl.h9
-rw-r--r--src/anonymous.c42
-rw-r--r--src/anonymous.h6
-rw-r--r--src/buffer.c391
-rw-r--r--src/buffer.h16
-rw-r--r--src/child.c611
-rw-r--r--src/child.h25
-rw-r--r--src/common.h10
-rw-r--r--src/conffile.c788
-rw-r--r--src/conffile.h4
-rw-r--r--src/conns.c168
-rw-r--r--src/conns.h121
-rw-r--r--src/daemon.c61
-rw-r--r--src/daemon.h4
-rw-r--r--src/filter.c302
-rw-r--r--src/filter.h17
-rw-r--r--src/hashmap.c594
-rw-r--r--src/hashmap.h37
-rw-r--r--src/heap.c135
-rw-r--r--src/heap.h22
-rw-r--r--src/html-error.c359
-rw-r--r--src/html-error.h19
-rw-r--r--src/http-message.c344
-rw-r--r--src/http-message.h24
-rw-r--r--src/log.c210
-rw-r--r--src/log.h14
-rw-r--r--src/network.c470
-rw-r--r--src/network.h12
-rw-r--r--src/reqs.c2745
-rw-r--r--src/reqs.h19
-rw-r--r--src/reverse-proxy.c216
-rw-r--r--src/reverse-proxy.h17
-rw-r--r--src/sock.c320
-rw-r--r--src/sock.h12
-rw-r--r--src/stats.c195
-rw-r--r--src/stats.h19
-rw-r--r--src/text.c82
-rw-r--r--src/text.h10
-rw-r--r--src/tinyproxy.c666
-rw-r--r--src/tinyproxy.h108
-rw-r--r--src/transparent-proxy.c144
-rw-r--r--src/transparent-proxy.h7
-rw-r--r--src/utils.c308
-rw-r--r--src/utils.h9
-rw-r--r--src/vector.c184
-rw-r--r--src/vector.h22
47 files changed, 5372 insertions, 5029 deletions
diff --git a/src/acl.c b/src/acl.c
index d61ccf3..50cc73f 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -33,23 +33,27 @@
/* Define how long an IPv6 address is in bytes (128 bits, 16 bytes) */
#define IPV6_LEN 16
-enum acl_type { ACL_STRING, ACL_NUMERIC };
+enum acl_type
+{ ACL_STRING, ACL_NUMERIC };
/*
* Hold the information about a particular access control. We store
* whether it's an ALLOW or DENY entry, and also whether it's a string
* entry (like a domain name) or an IP entry.
*/
-struct acl_s {
- acl_access_t access;
- enum acl_type type;
- union {
- char *string;
- struct {
- unsigned char octet[IPV6_LEN];
- unsigned char mask[IPV6_LEN];
- } ip;
- } address;
+struct acl_s
+{
+ acl_access_t access;
+ enum acl_type type;
+ union
+ {
+ char *string;
+ struct
+ {
+ unsigned char octet[IPV6_LEN];
+ unsigned char mask[IPV6_LEN];
+ } ip;
+ } address;
};
/*
@@ -67,41 +71,45 @@ static vector_t access_list = NULL;
*
*/
inline static int
-fill_netmask_array(char *bitmask_string, unsigned char array[], unsigned int len)
+fill_netmask_array (char *bitmask_string, unsigned char array[],
+ unsigned int len)
{
- unsigned int i;
- long int mask;
- char *endptr;
-
- errno = 0; /* to distinguish success/failure after call */
- mask = strtol(bitmask_string, &endptr, 10);
-
- /* check for various conversion errors */
- if ((errno == ERANGE && (mask == LONG_MIN || mask == LONG_MAX))
- || (errno != 0 && mask == 0)
- || (endptr == bitmask_string))
- return -1;
-
- /* valid range for a bit mask */
- if (mask < 0 || mask > (8 * len))
- return -1;
-
- /* we have a valid range to fill in the array */
- for (i = 0; i != len; ++i) {
- if (mask >= 8) {
- array[i] = 0xff;
- mask -= 8;
- }
- else if (mask > 0) {
- array[i] = (unsigned char)(0xff << (8 - mask));
- mask = 0;
- }
- else {
- array[i] = 0;
- }
- }
-
- return 0;
+ unsigned int i;
+ long int mask;
+ char *endptr;
+
+ errno = 0; /* to distinguish success/failure after call */
+ mask = strtol (bitmask_string, &endptr, 10);
+
+ /* check for various conversion errors */
+ if ((errno == ERANGE && (mask == LONG_MIN || mask == LONG_MAX))
+ || (errno != 0 && mask == 0) || (endptr == bitmask_string))
+ return -1;
+
+ /* valid range for a bit mask */
+ if (mask < 0 || mask > (8 * len))
+ return -1;
+
+ /* we have a valid range to fill in the array */
+ for (i = 0; i != len; ++i)
+ {
+ if (mask >= 8)
+ {
+ array[i] = 0xff;
+ mask -= 8;
+ }
+ else if (mask > 0)
+ {
+ array[i] = (unsigned char) (0xff << (8 - mask));
+ mask = 0;
+ }
+ else
+ {
+ array[i] = 0;
+ }
+ }
+
+ return 0;
}
@@ -115,74 +123,82 @@ fill_netmask_array(char *bitmask_string, unsigned char array[], unsigned int len
* 0 otherwise.
*/
int
-insert_acl(char *location, acl_access_t access_type)
+insert_acl (char *location, acl_access_t access_type)
{
- struct acl_s acl;
- int ret;
- char *p, ip_dst[IPV6_LEN];
-
- assert(location != NULL);
-
- /*
- * If the access list has not been set up, create it.
- */
- if (!access_list) {
- access_list = vector_create();
- if (!access_list) {
- log_message(LOG_ERR,
- "Unable to allocate memory for access list");
- return -1;
- }
- }
-
- /*
- * Start populating the access control structure.
- */
- memset(&acl, 0, sizeof(struct acl_s));
- acl.access = access_type;
-
- /*
- * Check for a valid IP address (the simplest case) first.
- */
- if (full_inet_pton(location, ip_dst) > 0) {
- acl.type = ACL_NUMERIC;
- memcpy(acl.address.ip.octet, ip_dst, IPV6_LEN);
- memset(acl.address.ip.mask, 0xff, IPV6_LEN);
- } else {
- /*
- * At this point we're either a hostname or an
- * IP address with a slash.
- */
- p = strchr(location, '/');
- if (p != NULL) {
- /*
- * We have a slash, so it's intended to be an
- * IP address with mask
- */
- *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);
-
- if (fill_netmask_array(p + 1, &(acl.address.ip.mask[0]), IPV6_LEN) < 0)
- return -1;
- } else {
- /* In all likelihood a string */
- acl.type = ACL_STRING;
- acl.address.string = safestrdup(location);
- if (!acl.address.string)
- return -1;
- }
- }
-
- /*
- * Add the entry and then clean up.
- */
- ret = vector_append(access_list, &acl, sizeof(struct acl_s));
- safefree(acl.address.string);
- return ret;
+ struct acl_s acl;
+ int ret;
+ char *p, ip_dst[IPV6_LEN];
+
+ assert (location != NULL);
+
+ /*
+ * If the access list has not been set up, create it.
+ */
+ if (!access_list)
+ {
+ access_list = vector_create ();
+ if (!access_list)
+ {
+ log_message (LOG_ERR, "Unable to allocate memory for access list");
+ return -1;
+ }
+ }
+
+ /*
+ * Start populating the access control structure.
+ */
+ memset (&acl, 0, sizeof (struct acl_s));
+ acl.access = access_type;
+
+ /*
+ * Check for a valid IP address (the simplest case) first.
+ */
+ if (full_inet_pton (location, ip_dst) > 0)
+ {
+ acl.type = ACL_NUMERIC;
+ memcpy (acl.address.ip.octet, ip_dst, IPV6_LEN);
+ memset (acl.address.ip.mask, 0xff, IPV6_LEN);
+ }
+ else
+ {
+ /*
+ * At this point we're either a hostname or an
+ * IP address with a slash.
+ */
+ p = strchr (location, '/');
+ if (p != NULL)
+ {
+ /*
+ * We have a slash, so it's intended to be an
+ * IP address with mask
+ */
+ *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);
+
+ if (fill_netmask_array (p + 1, &(acl.address.ip.mask[0]), IPV6_LEN)
+ < 0)
+ return -1;
+ }
+ else
+ {
+ /* In all likelihood a string */
+ acl.type = ACL_STRING;
+ acl.address.string = safestrdup (location);
+ if (!acl.address.string)
+ return -1;
+ }
+ }
+
+ /*
+ * Add the entry and then clean up.
+ */
+ ret = vector_append (access_list, &acl, sizeof (struct acl_s));
+ safefree (acl.address.string);
+ return ret;
}
/*
@@ -195,73 +211,79 @@ 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];
-
- 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;
+ 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;
}
/*
@@ -273,28 +295,29 @@ acl_string_processing(struct acl_s *acl,
* -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);
+ 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) {
- x = addr[i] & acl->address.ip.mask[i];
- y = acl->address.ip.octet[i] & acl->address.ip.mask[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;
- }
+ /* 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);
}
/*
@@ -305,50 +328,52 @@ 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;
- size_t i;
-
- assert(fd >= 0);
- assert(ip != NULL);
- assert(host != NULL);
-
- /*
- * 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;
- }
-
- /*
- * Check the return value too see if the IP address is
- * 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;
+ struct acl_s *acl;
+ int perm;
+ size_t i;
+
+ assert (fd >= 0);
+ assert (ip != NULL);
+ assert (host != NULL);
+
+ /*
+ * 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;
+ }
+
+ /*
+ * Check the return value too see if the IP address is
+ * 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;
}
diff --git a/src/acl.h b/src/acl.h
index 0722ec0..7a0f87b 100644
--- a/src/acl.h
+++ b/src/acl.h
@@ -21,10 +21,11 @@
#ifndef TINYPROXY_ACL_H
#define TINYPROXY_ACL_H
-typedef enum { ACL_ALLOW, ACL_DENY } acl_access_t;
+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 insert_acl (char *location, acl_access_t access_type);
+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 488d278..dd16421 100644
--- a/src/anonymous.c
+++ b/src/anonymous.c
@@ -30,9 +30,9 @@
static hashmap_t anonymous_map = NULL;
short int
-is_anonymous_enabled(void)
+is_anonymous_enabled (void)
{
- return (anonymous_map != NULL) ? 1 : 0;
+ return (anonymous_map != NULL) ? 1 : 0;
}
/*
@@ -40,12 +40,12 @@ is_anonymous_enabled(void)
* zero if the string was found, zero if it wasn't and negative upon error.
*/
int
-anonymous_search(char *s)
+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);
}
/*
@@ -55,23 +55,25 @@ anonymous_search(char *s)
* successful.
*/
int
-anonymous_insert(char *s)
+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/anonymous.h b/src/anonymous.h
index c3a01be..b6c93be 100644
--- a/src/anonymous.h
+++ b/src/anonymous.h
@@ -21,8 +21,8 @@
#ifndef _TINYPROXY_ANONYMOUS_H_
#define _TINYPROXY_ANONYMOUS_H_
-extern short int is_anonymous_enabled(void);
-extern int anonymous_search(char *s);
-extern int anonymous_insert(char *s);
+extern short int is_anonymous_enabled (void);
+extern int anonymous_search (char *s);
+extern int anonymous_insert (char *s);
#endif
diff --git a/src/buffer.c b/src/buffer.c
index 75bd59b..34aeefb 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -34,21 +34,23 @@
#define BUFFER_HEAD(x) (x)->head
#define BUFFER_TAIL(x) (x)->tail
-struct bufline_s {
- unsigned char *string; /* the actual string of data */
- struct bufline_s *next; /* pointer to next in linked list */
- size_t length; /* length of the string of data */
- size_t pos; /* start sending from this offset */
+struct bufline_s
+{
+ unsigned char *string; /* the actual string of data */
+ struct bufline_s *next; /* pointer to next in linked list */
+ size_t length; /* length of the string of data */
+ size_t pos; /* start sending from this offset */
};
/*
* The buffer structure points to the beginning and end of the buffer list
* (and includes the total size)
*/
-struct buffer_s {
- struct bufline_s *head; /* top of the buffer */
- struct bufline_s *tail; /* bottom of the buffer */
- size_t size; /* total size of the buffer */
+struct buffer_s
+{
+ struct bufline_s *head; /* top of the buffer */
+ struct bufline_s *tail; /* bottom of the buffer */
+ size_t size; /* total size of the buffer */
};
/*
@@ -57,155 +59,158 @@ struct buffer_s {
* data buffer on the heap, delete it because you now have TWO copies.
*/
static struct bufline_s *
-makenewline(unsigned char *data, size_t length)
+makenewline (unsigned char *data, size_t length)
{
- struct bufline_s *newline;
+ struct bufline_s *newline;
- assert(data != NULL);
- assert(length > 0);
+ assert (data != NULL);
+ assert (length > 0);
- if (!(newline = safemalloc(sizeof(struct bufline_s))))
- return NULL;
+ if (!(newline = safemalloc (sizeof (struct bufline_s))))
+ return NULL;
- if (!(newline->string = safemalloc(length))) {
- safefree(newline);
- return NULL;
- }
+ if (!(newline->string = safemalloc (length)))
+ {
+ safefree (newline);
+ return NULL;
+ }
- memcpy(newline->string, data, length);
+ memcpy (newline->string, data, length);
- newline->next = NULL;
- newline->length = length;
+ newline->next = NULL;
+ newline->length = length;
- /* Position our "read" pointer at the beginning of the data */
- newline->pos = 0;
+ /* Position our "read" pointer at the beginning of the data */
+ newline->pos = 0;
- return newline;
+ return newline;
}
/*
* Free the allocated buffer line
*/
static void
-free_line(struct bufline_s *line)
+free_line (struct bufline_s *line)
{
- assert(line != NULL);
+ assert (line != NULL);
- if (!line)
- return;
+ if (!line)
+ return;
- if (line->string)
- safefree(line->string);
+ if (line->string)
+ safefree (line->string);
- safefree(line);
+ safefree (line);
}
/*
* Create a new buffer
*/
struct buffer_s *
-new_buffer(void)
+new_buffer (void)
{
- struct buffer_s *buffptr;
+ struct buffer_s *buffptr;
- if (!(buffptr = safemalloc(sizeof(struct buffer_s))))
- return NULL;
+ if (!(buffptr = safemalloc (sizeof (struct buffer_s))))
+ return NULL;
- /*
- * Since the buffer is initially empty, set the HEAD and TAIL
- * pointers to NULL since they can't possibly point anywhere at the
- * moment.
- */
- BUFFER_HEAD(buffptr) = BUFFER_TAIL(buffptr) = NULL;
- buffptr->size = 0;
+ /*
+ * Since the buffer is initially empty, set the HEAD and TAIL
+ * pointers to NULL since they can't possibly point anywhere at the
+ * moment.
+ */
+ BUFFER_HEAD (buffptr) = BUFFER_TAIL (buffptr) = NULL;
+ buffptr->size = 0;
- return buffptr;
+ return buffptr;
}
/*
* Delete all the lines in the buffer and the buffer itself
*/
void
-delete_buffer(struct buffer_s *buffptr)
+delete_buffer (struct buffer_s *buffptr)
{
- struct bufline_s *next;
+ struct bufline_s *next;
- assert(buffptr != NULL);
+ assert (buffptr != NULL);
- while (BUFFER_HEAD(buffptr)) {
- next = BUFFER_HEAD(buffptr)->next;
- free_line(BUFFER_HEAD(buffptr));
- BUFFER_HEAD(buffptr) = next;
- }
+ while (BUFFER_HEAD (buffptr))
+ {
+ next = BUFFER_HEAD (buffptr)->next;
+ free_line (BUFFER_HEAD (buffptr));
+ BUFFER_HEAD (buffptr) = next;
+ }
- safefree(buffptr);
+ safefree (buffptr);
}
/*
* Return the current size of the buffer.
*/
size_t
-buffer_size(struct buffer_s *buffptr)
+buffer_size (struct buffer_s *buffptr)
{
- return buffptr->size;
+ return buffptr->size;
}
/*
* Push a new line on to the end of the buffer.
*/
int
-add_to_buffer(struct buffer_s *buffptr, unsigned char *data, size_t length)
+add_to_buffer (struct buffer_s *buffptr, unsigned char *data, size_t length)
{
- struct bufline_s *newline;
-
- assert(buffptr != NULL);
- assert(data != NULL);
- assert(length > 0);
-
- /*
- * Sanity check here. A buffer with a non-NULL head pointer must
- * have a size greater than zero, and vice-versa.
- */
- if (BUFFER_HEAD(buffptr) == NULL)
- assert(buffptr->size == 0);
- else
- assert(buffptr->size > 0);
-
- /*
- * Make a new line so we can add it to the buffer.
- */
- if (!(newline = makenewline(data, length)))
- return -1;
-
- if (buffptr->size == 0)
- BUFFER_HEAD(buffptr) = BUFFER_TAIL(buffptr) = newline;
- else {
- BUFFER_TAIL(buffptr)->next = newline;
- BUFFER_TAIL(buffptr) = newline;
- }
-
- buffptr->size += length;
-
- return 0;
+ struct bufline_s *newline;
+
+ assert (buffptr != NULL);
+ assert (data != NULL);
+ assert (length > 0);
+
+ /*
+ * Sanity check here. A buffer with a non-NULL head pointer must
+ * have a size greater than zero, and vice-versa.
+ */
+ if (BUFFER_HEAD (buffptr) == NULL)
+ assert (buffptr->size == 0);
+ else
+ assert (buffptr->size > 0);
+
+ /*
+ * Make a new line so we can add it to the buffer.
+ */
+ if (!(newline = makenewline (data, length)))
+ return -1;
+
+ if (buffptr->size == 0)
+ BUFFER_HEAD (buffptr) = BUFFER_TAIL (buffptr) = newline;
+ else
+ {
+ BUFFER_TAIL (buffptr)->next = newline;
+ BUFFER_TAIL (buffptr) = newline;
+ }
+
+ buffptr->size += length;
+
+ return 0;
}
/*
* Remove the first line from the top of the buffer
*/
static struct bufline_s *
-remove_from_buffer(struct buffer_s *buffptr)
+remove_from_buffer (struct buffer_s *buffptr)
{
- struct bufline_s *line;
+ struct bufline_s *line;
- assert(buffptr != NULL);
- assert(BUFFER_HEAD(buffptr) != NULL);
+ assert (buffptr != NULL);
+ assert (BUFFER_HEAD (buffptr) != NULL);
- line = BUFFER_HEAD(buffptr);
- BUFFER_HEAD(buffptr) = line->next;
+ line = BUFFER_HEAD (buffptr);
+ BUFFER_HEAD (buffptr) = line->next;
- buffptr->size -= line->length;
+ buffptr->size -= line->length;
- return line;
+ return line;
}
/*
@@ -214,61 +219,69 @@ remove_from_buffer(struct buffer_s *buffptr)
*/
#define READ_BUFFER_SIZE (1024 * 2)
ssize_t
-read_buffer(int fd, struct buffer_s * buffptr)
+read_buffer (int fd, struct buffer_s * buffptr)
{
- ssize_t bytesin;
- unsigned char *buffer;
-
- assert(fd >= 0);
- assert(buffptr != NULL);
-
- /*
- * Don't allow the buffer to grow larger than MAXBUFFSIZE
- */
- if (buffptr->size >= MAXBUFFSIZE)
- return 0;
-
- buffer = safemalloc(READ_BUFFER_SIZE);
- if (!buffer) {
- return -ENOMEM;
- }
-
- bytesin = read(fd, buffer, READ_BUFFER_SIZE);
-
- if (bytesin > 0) {
- if (add_to_buffer(buffptr, buffer, bytesin) < 0) {
- log_message(LOG_ERR,
- "readbuff: add_to_buffer() error.");
- bytesin = -1;
- }
- } else {
- if (bytesin == 0) {
- /* connection was closed by client */
- bytesin = -1;
- } else {
- switch (errno) {
+ ssize_t bytesin;
+ unsigned char *buffer;
+
+ assert (fd >= 0);
+ assert (buffptr != NULL);
+
+ /*
+ * Don't allow the buffer to grow larger than MAXBUFFSIZE
+ */
+ if (buffptr->size >= MAXBUFFSIZE)
+ return 0;
+
+ buffer = safemalloc (READ_BUFFER_SIZE);
+ if (!buffer)
+ {
+ return -ENOMEM;
+ }
+
+ bytesin = read (fd, buffer, READ_BUFFER_SIZE);
+
+ if (bytesin > 0)
+ {
+ if (add_to_buffer (buffptr, buffer, bytesin) < 0)
+ {
+ log_message (LOG_ERR, "readbuff: add_to_buffer() error.");
+ bytesin = -1;
+ }
+ }
+ else
+ {
+ if (bytesin == 0)
+ {
+ /* connection was closed by client */
+ bytesin = -1;
+ }
+ else
+ {
+ switch (errno)
+ {
#ifdef EWOULDBLOCK
- case EWOULDBLOCK:
+ case EWOULDBLOCK:
#else
# ifdef EAGAIN
- case EAGAIN:
+ case EAGAIN:
# endif
#endif
- case EINTR:
- bytesin = 0;
- break;
- default:
- log_message(LOG_ERR,
- "readbuff: recv() error \"%s\" on file descriptor %d",
- strerror(errno), fd);
- bytesin = -1;
- break;
- }
- }
- }
-
- safefree(buffer);
- return bytesin;
+ case EINTR:
+ bytesin = 0;
+ break;
+ default:
+ log_message (LOG_ERR,
+ "readbuff: recv() error \"%s\" on file descriptor %d",
+ strerror (errno), fd);
+ bytesin = -1;
+ break;
+ }
+ }
+ }
+
+ safefree (buffer);
+ return bytesin;
}
/*
@@ -276,53 +289,57 @@ read_buffer(int fd, struct buffer_s * buffptr)
* Takes a connection and returns the number of bytes written.
*/
ssize_t
-write_buffer(int fd, struct buffer_s * buffptr)
+write_buffer (int fd, struct buffer_s * buffptr)
{
- ssize_t bytessent;
- struct bufline_s *line;
-
- assert(fd >= 0);
- assert(buffptr != NULL);
-
- if (buffptr->size == 0)
- return 0;
-
- /* Sanity check. It would be bad to be using a NULL pointer! */
- assert(BUFFER_HEAD(buffptr) != NULL);
- line = BUFFER_HEAD(buffptr);
-
- bytessent =
- send(fd, line->string + line->pos, line->length - line->pos,
- MSG_NOSIGNAL);
-
- if (bytessent >= 0) {
- /* bytes sent, adjust buffer */
- line->pos += bytessent;
- if (line->pos == line->length)
- free_line(remove_from_buffer(buffptr));
- return bytessent;
- } else {
- switch (errno) {
+ ssize_t bytessent;
+ struct bufline_s *line;
+
+ assert (fd >= 0);
+ assert (buffptr != NULL);
+
+ if (buffptr->size == 0)
+ return 0;
+
+ /* Sanity check. It would be bad to be using a NULL pointer! */
+ assert (BUFFER_HEAD (buffptr) != NULL);
+ line = BUFFER_HEAD (buffptr);
+
+ bytessent =
+ send (fd, line->string + line->pos, line->length - line->pos,
+ MSG_NOSIGNAL);
+
+ if (bytessent >= 0)
+ {
+ /* bytes sent, adjust buffer */
+ line->pos += bytessent;
+ if (line->pos == line->length)
+ free_line (remove_from_buffer (buffptr));
+ return bytessent;
+ }
+ else
+ {
+ switch (errno)
+ {
#ifdef EWOULDBLOCK
- case EWOULDBLOCK:
+ case EWOULDBLOCK:
#else
# ifdef EAGAIN
- case EAGAIN:
+ case EAGAIN:
# endif
#endif
- case EINTR:
- return 0;
- case ENOBUFS:
- case ENOMEM:
- log_message(LOG_ERR,
- "writebuff: write() error [NOBUFS/NOMEM] \"%s\" on file descriptor %d",
- strerror(errno), fd);
- return 0;
- default:
- log_message(LOG_ERR,
- "writebuff: write() error \"%s\" on file descriptor %d",
- strerror(errno), fd);
- return -1;
- }
- }
+ case EINTR:
+ return 0;
+ case ENOBUFS:
+ case ENOMEM:
+ log_message (LOG_ERR,
+ "writebuff: write() error [NOBUFS/NOMEM] \"%s\" on file descriptor %d",
+ strerror (errno), fd);
+ return 0;
+ default:
+ log_message (LOG_ERR,
+ "writebuff: write() error \"%s\" on file descriptor %d",
+ strerror (errno), fd);
+ return -1;
+ }
+ }
}
diff --git a/src/buffer.h b/src/buffer.h
index cb4d245..ff1167f 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -24,17 +24,17 @@
/* Forward declaration */
struct buffer_s;
-extern struct buffer_s *new_buffer(void);
-extern void delete_buffer(struct buffer_s *buffptr);
-extern size_t buffer_size(struct buffer_s *buffptr);
+extern struct buffer_s *new_buffer (void);
+extern void delete_buffer (struct buffer_s *buffptr);
+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);
+extern int add_to_buffer (struct buffer_s *buffptr, unsigned char *data,
+ 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);
+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 1bb1802..25b95b8 100644
--- a/src/child.c
+++ b/src/child.c
@@ -37,11 +37,13 @@ static socklen_t addrlen;
/*
* Stores the internal data needed for each child (connection)
*/
-enum child_status_t { T_EMPTY, T_WAITING, T_CONNECTED };
-struct child_s {
- pid_t tid;
- unsigned int connects;
- enum child_status_t status;
+enum child_status_t
+{ T_EMPTY, T_WAITING, T_CONNECTED };
+struct child_s
+{
+ pid_t tid;
+ unsigned int connects;
+ enum child_status_t status;
};
/*
@@ -50,12 +52,13 @@ struct child_s {
*/
static struct child_s *child_ptr;
-static struct child_config_s {
- int maxclients, maxrequestsperchild;
- int maxspareservers, minspareservers, startservers;
+static struct child_config_s
+{
+ 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
@@ -74,47 +77,48 @@ static struct flock lock_it, unlock_it;
static int lock_fd = -1;
static void
-_child_lock_init(void)
+_child_lock_init (void)
{
- char lock_file[] = "/tmp/tinyproxy.servers.lock.XXXXXX";
+ char lock_file[] = "/tmp/tinyproxy.servers.lock.XXXXXX";
- /* Only allow u+rw bits. This may be required for some versions
- * of glibc so that mkstemp() doesn't make us vulnerable.
- */
- umask(0177);
+ /* Only allow u+rw bits. This may be required for some versions
+ * of glibc so that mkstemp() doesn't make us vulnerable.
+ */
+ umask (0177);
- 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)
+_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)
+_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 */
@@ -138,126 +142,133 @@ _child_lock_release(void)
* Set the configuration values for the various child related settings.
*/
short int
-child_configure(child_config_t type, int val)
+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);
}
/*
@@ -265,104 +276,113 @@ 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;
+ pid_t pid;
- if ((pid = fork()) > 0)
- return pid; /* parent */
+ 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);
+ /*
+ * 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;
+ child_main (ptr); /* never returns */
+ return -1;
}
/*
* Create a pool of children to handle incoming connections
*/
short int
-child_pool_create(void)
+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;
}
/*
@@ -370,88 +390,95 @@ child_pool_create(void)
* servers. It monitors this at least once a second.
*/
void
-child_main_loop(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;
+ }
+ }
}
/*
* Go through all the non-empty children and cancel them.
*/
void
-child_kill_children(void)
+child_kill_children (void)
{
- unsigned int i;
+ unsigned int i;
- for (i = 0; i != child_config.maxclients; i++) {
- if (child_ptr[i].status != T_EMPTY)
- kill(child_ptr[i].tid, SIGTERM);
- }
+ 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)
+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)
+child_close_sock (void)
{
- close(listenfd);
+ close (listenfd);
}
diff --git a/src/child.h b/src/child.h
index 65fbb9f..dc19360 100644
--- a/src/child.h
+++ b/src/child.h
@@ -21,20 +21,21 @@
#ifndef TINYPROXY_CHILD_H
#define TINYPROXY_CHILD_H
-typedef enum {
- CHILD_MAXCLIENTS,
- CHILD_MAXSPARESERVERS,
- CHILD_MINSPARESERVERS,
- CHILD_STARTSERVERS,
- CHILD_MAXREQUESTSPERCHILD
+typedef enum
+{
+ CHILD_MAXCLIENTS,
+ CHILD_MAXSPARESERVERS,
+ CHILD_MINSPARESERVERS,
+ CHILD_STARTSERVERS,
+ CHILD_MAXREQUESTSPERCHILD
} child_config_t;
-extern short int child_pool_create(void);
-extern int child_listening_sock(uint16_t port);
-extern void child_close_sock(void);
-extern void child_main_loop(void);
-extern void child_kill_children(void);
+extern short int child_pool_create (void);
+extern int child_listening_sock (uint16_t port);
+extern void child_close_sock (void);
+extern void child_main_loop (void);
+extern void child_kill_children (void);
-extern short int child_configure(child_config_t type, int val);
+extern short int child_configure (child_config_t type, int val);
#endif
diff --git a/src/common.h b/src/common.h
index 551d0f9..ab71322 100644
--- a/src/common.h
+++ b/src/common.h
@@ -173,13 +173,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 78f5da3..85bab7e 100644
--- a/src/conffile.c
+++ b/src/conffile.c
@@ -66,7 +66,8 @@
* 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
@@ -86,55 +87,55 @@ typedef int (*CONFFILE_HANDLER) (struct config_s *, const char *, regmatch_t[]);
* to be in-scope before the big structure below.
*/
static
-HANDLE_FUNC(handle_nop)
+HANDLE_FUNC (handle_nop)
{
- return 0;
-} /* do nothing function */
+ return 0;
+} /* do nothing function */
-static HANDLE_FUNC(handle_allow);
-static HANDLE_FUNC(handle_anonymous);
-static HANDLE_FUNC(handle_bind);
-static HANDLE_FUNC(handle_bindsame);
-static HANDLE_FUNC(handle_connectport);
-static HANDLE_FUNC(handle_defaulterrorfile);
-static HANDLE_FUNC(handle_deny);
-static HANDLE_FUNC(handle_errorfile);
+static HANDLE_FUNC (handle_allow);
+static HANDLE_FUNC (handle_anonymous);
+static HANDLE_FUNC (handle_bind);
+static HANDLE_FUNC (handle_bindsame);
+static HANDLE_FUNC (handle_connectport);
+static HANDLE_FUNC (handle_defaulterrorfile);
+static HANDLE_FUNC (handle_deny);
+static HANDLE_FUNC (handle_errorfile);
#ifdef FILTER_ENABLE
-static HANDLE_FUNC(handle_filter);
-static HANDLE_FUNC(handle_filtercasesensitive);
-static HANDLE_FUNC(handle_filterdefaultdeny);
-static HANDLE_FUNC(handle_filterextended);
-static HANDLE_FUNC(handle_filterurls);
+static HANDLE_FUNC (handle_filter);
+static HANDLE_FUNC (handle_filtercasesensitive);
+static HANDLE_FUNC (handle_filterdefaultdeny);
+static HANDLE_FUNC (handle_filterextended);
+static HANDLE_FUNC (handle_filterurls);
#endif
-static HANDLE_FUNC(handle_group);
-static HANDLE_FUNC(handle_listen);
-static HANDLE_FUNC(handle_logfile);
-static HANDLE_FUNC(handle_loglevel);
-static HANDLE_FUNC(handle_maxclients);
-static HANDLE_FUNC(handle_maxrequestsperchild);
-static HANDLE_FUNC(handle_maxspareservers);
-static HANDLE_FUNC(handle_minspareservers);
-static HANDLE_FUNC(handle_pidfile);
-static HANDLE_FUNC(handle_port);
+static HANDLE_FUNC (handle_group);
+static HANDLE_FUNC (handle_listen);
+static HANDLE_FUNC (handle_logfile);
+static HANDLE_FUNC (handle_loglevel);
+static HANDLE_FUNC (handle_maxclients);
+static HANDLE_FUNC (handle_maxrequestsperchild);
+static HANDLE_FUNC (handle_maxspareservers);
+static HANDLE_FUNC (handle_minspareservers);
+static HANDLE_FUNC (handle_pidfile);
+static HANDLE_FUNC (handle_port);
#ifdef REVERSE_SUPPORT
-static HANDLE_FUNC(handle_reversebaseurl);
-static HANDLE_FUNC(handle_reversemagic);
-static HANDLE_FUNC(handle_reverseonly);
-static HANDLE_FUNC(handle_reversepath);
+static HANDLE_FUNC (handle_reversebaseurl);
+static HANDLE_FUNC (handle_reversemagic);
+static HANDLE_FUNC (handle_reverseonly);
+static HANDLE_FUNC (handle_reversepath);
#endif
-static HANDLE_FUNC(handle_startservers);
-static HANDLE_FUNC(handle_statfile);
-static HANDLE_FUNC(handle_stathost);
-static HANDLE_FUNC(handle_syslog);
-static HANDLE_FUNC(handle_timeout);
+static HANDLE_FUNC (handle_startservers);
+static HANDLE_FUNC (handle_statfile);
+static HANDLE_FUNC (handle_stathost);
+static HANDLE_FUNC (handle_syslog);
+static HANDLE_FUNC (handle_timeout);
-static HANDLE_FUNC(handle_user);
-static HANDLE_FUNC(handle_viaproxyname);
-static HANDLE_FUNC(handle_xtinyproxy);
+static HANDLE_FUNC (handle_user);
+static HANDLE_FUNC (handle_viaproxyname);
+static HANDLE_FUNC (handle_xtinyproxy);
#ifdef UPSTREAM_SUPPORT
-static HANDLE_FUNC(handle_upstream);
-static HANDLE_FUNC(handle_upstream_no);
+static HANDLE_FUNC (handle_upstream);
+static HANDLE_FUNC (handle_upstream_no);
#endif
/*
@@ -156,82 +157,77 @@ static HANDLE_FUNC(handle_upstream_no);
* for internal use, a pointer to the compiled regex so it only needs
* to be compiled one.
*/
-struct {
- const char *re;
- CONFFILE_HANDLER handler;
- 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),
-
+struct
+{
+ const char *re;
+ CONFFILE_HANDLER handler;
+ 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),
#ifdef FILTER_ENABLE
- /* 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),
+ /* 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),
#endif
-
#ifdef REVERSE_SUPPORT
- /* 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),
+ /* 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),
#endif
-
#ifdef UPSTREAM_SUPPORT
- /* upstream is rather complicated */
- { BEGIN "(no" WS "upstream)" WS STR END, handle_upstream_no },
- { BEGIN "(upstream)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR ")?" END, handle_upstream },
+ /* upstream is rather complicated */
+ {
+ BEGIN "(no" WS "upstream)" WS STR END, handle_upstream_no},
+ {
+ BEGIN "(upstream)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR ")?" END,
+ handle_upstream},
#endif
-
- /* loglevel */
- STDCONF("loglevel", "(critical|error|warning|notice|connect|info)",
- handle_loglevel)
-};
-const unsigned int ndirectives = sizeof(directives) / sizeof(directives[0]);
+ /* loglevel */
+STDCONF ("loglevel", "(critical|error|warning|notice|connect|info)",
+ handle_loglevel)};
+const unsigned int ndirectives = sizeof (directives) / sizeof (directives[0]);
/*
* Compiles the regular expressions used by the configuration file. This
@@ -240,25 +236,25 @@ const unsigned int ndirectives = sizeof(directives) / sizeof(directives[0]);
* Returns 0 on success; negative upon failure.
*/
int
-config_compile(void)
+config_compile (void)
{
- int i, r;
+ int i, r;
- for (i = 0; i != ndirectives; ++i) {
- assert(directives[i].handler);
- assert(!directives[i].cre);
+ 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;
+ directives[i].cre = safemalloc (sizeof (regex_t));
+ if (!directives[i].cre)
+ return -1;
- r = regcomp(directives[i].cre,
- directives[i].re,
- REG_EXTENDED | REG_ICASE | REG_NEWLINE);
- if (r)
- return r;
- }
- return 0;
+ r = regcomp (directives[i].cre,
+ directives[i].re, REG_EXTENDED | REG_ICASE | REG_NEWLINE);
+ if (r)
+ return r;
+ }
+ return 0;
}
/*
@@ -270,39 +266,42 @@ 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;
+ regmatch_t match[RE_MAX_MATCHES];
+ unsigned int i;
- assert(ndirectives > 0);
+ assert (ndirectives > 0);
- 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);
- }
+ 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 -1;
+ return -1;
}
/*
* 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 */
- unsigned long lineno = 1;
+ char buffer[1024]; /* 1KB lines should be plenty */
+ unsigned long lineno = 1;
- while (fgets(buffer, sizeof(buffer), f)) {
- if (check_match(conf, buffer)) {
- printf("Syntax error on line %ld\n", lineno);
- return 1;
- }
- ++lineno;
- }
- return 0;
+ while (fgets (buffer, sizeof (buffer), f))
+ {
+ if (check_match (conf, buffer))
+ {
+ printf ("Syntax error on line %ld\n", lineno);
+ return 1;
+ }
+ ++lineno;
+ }
+ return 0;
}
/***********************************************************************
@@ -313,78 +312,79 @@ config_parse(struct config_s *conf, FILE * f)
***********************************************************************/
static char *
-get_string_arg(const char *line, regmatch_t * match)
+get_string_arg (const char *line, regmatch_t * match)
{
- char *p;
- const unsigned int len = match->rm_eo - match->rm_so;
+ char *p;
+ const unsigned int len = match->rm_eo - match->rm_so;
- assert(line);
- assert(len > 0);
+ assert (line);
+ assert (len > 0);
- p = safemalloc(len + 1);
- if (!p)
- return NULL;
+ p = safemalloc (len + 1);
+ if (!p)
+ return NULL;
- memcpy(p, line + match->rm_so, len);
- p[len] = '\0';
- return p;
+ memcpy (p, line + match->rm_so, len);
+ p[len] = '\0';
+ return p;
}
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);
- safefree(arg);
- return *var ? 0 : -1;
+ if (!arg)
+ return -1;
+ *var = safestrdup (arg);
+ safefree (arg);
+ return *var ? 0 : -1;
}
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);
+ assert (line);
+ assert (match && match->rm_so != -1);
- /* "y"es or o"n" map as true, otherwise it's false. */
- if (tolower(p[0]) == 'y' || tolower(p[1]) == 'n')
- return 1;
- else
- return 0;
+ /* "y"es or o"n" map as true, otherwise it's false. */
+ if (tolower (p[0]) == 'y' || tolower (p[1]) == 'n')
+ return 1;
+ else
+ return 0;
}
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);
+ assert (var);
+ assert (line);
+ assert (match && match->rm_so != -1);
- *var = get_bool_arg(line, match);
- return 0;
+ *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);
+ assert (line);
+ assert (match && match->rm_so != -1);
- return strtol(line + match->rm_so, NULL, 0);
+ 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);
+ assert (var);
+ assert (line);
+ assert (match);
- *var = get_int_arg(line, match);
- return 0;
+ *var = get_int_arg (line, match);
+ return 0;
}
/***********************************************************************
@@ -406,392 +406,404 @@ set_int_arg(int long *var, const char *line, regmatch_t * match)
***********************************************************************/
static
-HANDLE_FUNC(handle_logfile)
+HANDLE_FUNC (handle_logfile)
{
- return set_string_arg(&conf->logf_name, line, &match[2]);
+ return set_string_arg (&conf->logf_name, line, &match[2]);
}
static
-HANDLE_FUNC(handle_pidfile)
+HANDLE_FUNC (handle_pidfile)
{
- return set_string_arg(&conf->pidpath, line, &match[2]);
+ return set_string_arg (&conf->pidpath, line, &match[2]);
}
static
-HANDLE_FUNC(handle_anonymous)
+HANDLE_FUNC (handle_anonymous)
{
- char *arg = get_string_arg(line, &match[2]);
+ char *arg = get_string_arg (line, &match[2]);
- if (!arg)
- return -1;
+ if (!arg)
+ return -1;
- anonymous_insert(arg);
- safefree(arg);
- return 0;
+ anonymous_insert (arg);
+ safefree (arg);
+ return 0;
}
static
-HANDLE_FUNC(handle_viaproxyname)
+HANDLE_FUNC (handle_viaproxyname)
{
- int r = set_string_arg(&conf->via_proxy_name, line, &match[2]);
+ int r = set_string_arg (&conf->via_proxy_name, line, &match[2]);
- if (r)
- return r;
- log_message(LOG_INFO,
- "Setting \"Via\" header proxy to %s", conf->via_proxy_name);
- return 0;
+ if (r)
+ return r;
+ log_message (LOG_INFO,
+ "Setting \"Via\" header proxy to %s", conf->via_proxy_name);
+ return 0;
}
static
-HANDLE_FUNC(handle_defaulterrorfile)
+HANDLE_FUNC (handle_defaulterrorfile)
{
- return set_string_arg(&conf->errorpage_undef, line, &match[2]);
+ return set_string_arg (&conf->errorpage_undef, line, &match[2]);
}
static
-HANDLE_FUNC(handle_statfile)
+HANDLE_FUNC (handle_statfile)
{
- return set_string_arg(&conf->statpage, line, &match[2]);
+ return set_string_arg (&conf->statpage, line, &match[2]);
}
static
-HANDLE_FUNC(handle_stathost)
+HANDLE_FUNC (handle_stathost)
{
- int r = set_string_arg(&conf->stathost, line, &match[2]);
+ int r = set_string_arg (&conf->stathost, line, &match[2]);
- if (r)
- return r;
- log_message(LOG_INFO, "Stathost set to \"%s\"", conf->stathost);
- return 0;
+ if (r)
+ return r;
+ log_message (LOG_INFO, "Stathost set to \"%s\"", conf->stathost);
+ return 0;
}
static
-HANDLE_FUNC(handle_xtinyproxy)
+HANDLE_FUNC (handle_xtinyproxy)
{
#ifdef XTINYPROXY_ENABLE
- return set_string_arg(&conf->my_domain, line, &match[2]);
+ return set_string_arg (&conf->my_domain, line, &match[2]);
#else
- fprintf(stderr,
- "XTinyproxy NOT Enabled! Recompile with --enable-xtinyproxy\n");
- return 1;
+ fprintf (stderr,
+ "XTinyproxy NOT Enabled! Recompile with --enable-xtinyproxy\n");
+ return 1;
#endif
}
static
-HANDLE_FUNC(handle_syslog)
+HANDLE_FUNC (handle_syslog)
{
#ifdef HAVE_SYSLOG_H
- return set_bool_arg(&conf->syslog, line, &match[2]);
+ return set_bool_arg (&conf->syslog, line, &match[2]);
#else
- fprintf(stderr, "Syslog support not compiled in executable.\n");
- return 1;
+ fprintf (stderr, "Syslog support not compiled in executable.\n");
+ return 1;
#endif
}
static
-HANDLE_FUNC(handle_bindsame)
+HANDLE_FUNC (handle_bindsame)
{
- int r = set_bool_arg(&conf->bindsame, line, &match[2]);
+ int r = set_bool_arg (&conf->bindsame, line, &match[2]);
- if (r)
- return r;
- log_message(LOG_INFO, "Binding outgoing connection to incoming IP");
- return 0;
+ if (r)
+ return r;
+ log_message (LOG_INFO, "Binding outgoing connection to incoming IP");
+ return 0;
}
static
-HANDLE_FUNC(handle_port)
+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)
+HANDLE_FUNC (handle_maxclients)
{
- child_configure(CHILD_MAXCLIENTS, get_int_arg(line, &match[2]));
- return 0;
+ child_configure (CHILD_MAXCLIENTS, get_int_arg (line, &match[2]));
+ return 0;
}
static
-HANDLE_FUNC(handle_maxspareservers)
+HANDLE_FUNC (handle_maxspareservers)
{
- child_configure(CHILD_MAXSPARESERVERS, get_int_arg(line, &match[2]));
- return 0;
+ child_configure (CHILD_MAXSPARESERVERS, get_int_arg (line, &match[2]));
+ return 0;
}
static
-HANDLE_FUNC(handle_minspareservers)
+HANDLE_FUNC (handle_minspareservers)
{
- child_configure(CHILD_MINSPARESERVERS, get_int_arg(line, &match[2]));
- return 0;
+ child_configure (CHILD_MINSPARESERVERS, get_int_arg (line, &match[2]));
+ return 0;
}
static
-HANDLE_FUNC(handle_startservers)
+HANDLE_FUNC (handle_startservers)
{
- child_configure(CHILD_STARTSERVERS, get_int_arg(line, &match[2]));
- return 0;
+ child_configure (CHILD_STARTSERVERS, get_int_arg (line, &match[2]));
+ return 0;
}
static
-HANDLE_FUNC(handle_maxrequestsperchild)
+HANDLE_FUNC (handle_maxrequestsperchild)
{
- child_configure(CHILD_MAXREQUESTSPERCHILD,
- get_int_arg(line, &match[2]));
- return 0;
+ child_configure (CHILD_MAXREQUESTSPERCHILD, get_int_arg (line, &match[2]));
+ return 0;
}
static
-HANDLE_FUNC(handle_timeout)
+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)
+HANDLE_FUNC (handle_connectport)
{
- add_connect_port_allowed(get_int_arg(line, &match[2]));
- return 0;
+ add_connect_port_allowed (get_int_arg (line, &match[2]));
+ return 0;
}
static
-HANDLE_FUNC(handle_user)
+HANDLE_FUNC (handle_user)
{
- return set_string_arg(&conf->user, line, &match[2]);
+ return set_string_arg (&conf->user, line, &match[2]);
}
static
-HANDLE_FUNC(handle_group)
+HANDLE_FUNC (handle_group)
{
- return set_string_arg(&conf->group, line, &match[2]);
+ return set_string_arg (&conf->group, line, &match[2]);
}
static
-HANDLE_FUNC(handle_allow)
+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;
+ insert_acl (arg, ACL_ALLOW);
+ safefree (arg);
+ return 0;
}
static
-HANDLE_FUNC(handle_deny)
+HANDLE_FUNC (handle_deny)
{
- char *arg = get_string_arg(line, &match[2]);
+ char *arg = get_string_arg (line, &match[2]);
- insert_acl(arg, ACL_DENY);
- safefree(arg);
- return 0;
+ insert_acl (arg, ACL_DENY);
+ safefree (arg);
+ return 0;
}
static
-HANDLE_FUNC(handle_bind)
+HANDLE_FUNC (handle_bind)
{
#ifndef TRANSPARENT_PROXY
- int r = set_string_arg(&conf->bind_address, line, &match[2]);
+ int r = set_string_arg (&conf->bind_address, line, &match[2]);
- if (r)
- return r;
- log_message(LOG_INFO,
- "Outgoing connections bound to IP %s", conf->bind_address);
- return 0;
+ if (r)
+ return r;
+ log_message (LOG_INFO,
+ "Outgoing connections bound to IP %s", conf->bind_address);
+ return 0;
#else
- fprintf(stderr,
- "\"Bind\" cannot be used with transparent support enabled.\n");
- return 1;
+ fprintf (stderr,
+ "\"Bind\" cannot be used with transparent support enabled.\n");
+ return 1;
#endif
}
static
-HANDLE_FUNC(handle_listen)
+HANDLE_FUNC (handle_listen)
{
- int r = set_string_arg(&conf->ipAddr, line, &match[2]);
+ int r = set_string_arg (&conf->ipAddr, line, &match[2]);
- if (r)
- return r;
- log_message(LOG_INFO, "Listing on IP %s", conf->ipAddr);
- return 0;
+ if (r)
+ return r;
+ log_message (LOG_INFO, "Listing on IP %s", conf->ipAddr);
+ return 0;
}
static
-HANDLE_FUNC(handle_errorfile)
+HANDLE_FUNC (handle_errorfile)
{
- /*
- * Because an integer is defined as ((0x)?[[:digit:]]+) _two_
- * match places are used. match[2] matches the full digit
- * string, while match[3] matches only the "0x" part if
- * present. This is why the "string" is located at
- * match[4] (rather than the more intuitive match[3].
- */
- long int err = get_int_arg(line, &match[2]);
- char *page = get_string_arg(line, &match[4]);
+ /*
+ * Because an integer is defined as ((0x)?[[:digit:]]+) _two_
+ * match places are used. match[2] matches the full digit
+ * string, while match[3] matches only the "0x" part if
+ * present. This is why the "string" is located at
+ * match[4] (rather than the more intuitive match[3].
+ */
+ 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;
+ add_new_errorpage (page, err);
+ safefree (page);
+ return 0;
}
/*
* Log level's strings.
*/
-struct log_levels_s {
- const char *string;
- int level;
+struct log_levels_s
+{
+ 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)
+HANDLE_FUNC (handle_loglevel)
{
- static const unsigned int nlevels =
- sizeof(log_levels) / sizeof(log_levels[0]);
- unsigned int i;
+ static const unsigned int nlevels =
+ sizeof (log_levels) / sizeof (log_levels[0]);
+ unsigned int i;
- char *arg = get_string_arg(line, &match[2]);
+ 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);
- safefree(arg);
- return 0;
- }
- }
+ for (i = 0; i != nlevels; ++i)
+ {
+ if (!strcasecmp (arg, log_levels[i].string))
+ {
+ set_log_level (log_levels[i].level);
+ safefree (arg);
+ return 0;
+ }
+ }
- safefree(arg);
- return -1;
+ safefree (arg);
+ return -1;
}
#ifdef FILTER_ENABLE
static
-HANDLE_FUNC(handle_filter)
+HANDLE_FUNC (handle_filter)
{
- return set_string_arg(&conf->filter, line, &match[2]);
+ return set_string_arg (&conf->filter, line, &match[2]);
}
static
-HANDLE_FUNC(handle_filterurls)
+HANDLE_FUNC (handle_filterurls)
{
- return set_bool_arg(&conf->filter_url, line, &match[2]);
+ return set_bool_arg (&conf->filter_url, line, &match[2]);
}
static
-HANDLE_FUNC(handle_filterextended)
+HANDLE_FUNC (handle_filterextended)
{
- return set_bool_arg(&conf->filter_extended, line, &match[2]);
+ return set_bool_arg (&conf->filter_extended, line, &match[2]);
}
static
-HANDLE_FUNC(handle_filterdefaultdeny)
+HANDLE_FUNC (handle_filterdefaultdeny)
{
- assert(match[2].rm_so != -1);
+ assert (match[2].rm_so != -1);
- if (get_bool_arg(line, &match[2]))
- filter_set_default_policy(FILTER_DEFAULT_DENY);
- return 0;
+ if (get_bool_arg (line, &match[2]))
+ filter_set_default_policy (FILTER_DEFAULT_DENY);
+ return 0;
}
static
-HANDLE_FUNC(handle_filtercasesensitive)
+HANDLE_FUNC (handle_filtercasesensitive)
{
- return set_bool_arg(&conf->filter_casesensitive, line, &match[2]);
+ return set_bool_arg (&conf->filter_casesensitive, line, &match[2]);
}
#endif
#ifdef REVERSE_SUPPORT
static
-HANDLE_FUNC(handle_reverseonly)
+HANDLE_FUNC (handle_reverseonly)
{
- return set_bool_arg(&conf->reverseonly, line, &match[2]);
+ return set_bool_arg (&conf->reverseonly, line, &match[2]);
}
static
-HANDLE_FUNC(handle_reversemagic)
+HANDLE_FUNC (handle_reversemagic)
{
- return set_bool_arg(&conf->reversemagic, line, &match[2]);
+ return set_bool_arg (&conf->reversemagic, line, &match[2]);
}
static
-HANDLE_FUNC(handle_reversebaseurl)
+HANDLE_FUNC (handle_reversebaseurl)
{
- return set_string_arg(&conf->reversebaseurl, line, &match[2]);
+ return set_string_arg (&conf->reversebaseurl, line, &match[2]);
}
static
-HANDLE_FUNC(handle_reversepath)
+HANDLE_FUNC (handle_reversepath)
{
- /*
- * The second string argument is optional.
- */
- char *arg1, *arg2;
+ /*
+ * The second string argument is optional.
+ */
+ char *arg1, *arg2;
- arg1 = get_string_arg(line, &match[2]);
- if (!arg1)
- return -1;
+ arg1 = get_string_arg (line, &match[2]);
+ if (!arg1)
+ return -1;
- if (match[3].rm_so != -1) {
- arg2 = get_string_arg(line, &match[3]);
- if (!arg2) {
- safefree(arg1);
- return -1;
- }
- reversepath_add(arg1, arg2);
- safefree(arg1);
- safefree(arg2);
- } else {
- reversepath_add(NULL, arg1);
- safefree(arg1);
- }
- return 0;
+ if (match[3].rm_so != -1)
+ {
+ arg2 = get_string_arg (line, &match[3]);
+ if (!arg2)
+ {
+ safefree (arg1);
+ return -1;
+ }
+ reversepath_add (arg1, arg2);
+ safefree (arg1);
+ safefree (arg2);
+ }
+ else
+ {
+ reversepath_add (NULL, arg1);
+ safefree (arg1);
+ }
+ return 0;
}
#endif
#ifdef UPSTREAM_SUPPORT
static
-HANDLE_FUNC(handle_upstream)
+HANDLE_FUNC (handle_upstream)
{
- char *ip;
- int port;
- char *domain;
+ char *ip;
+ int port;
+ char *domain;
- ip = get_string_arg(line, &match[2]);
- if (!ip) return -1;
- port = get_int_arg(line, &match[7]);
+ ip = get_string_arg (line, &match[2]);
+ if (!ip)
+ return -1;
+ port = get_int_arg (line, &match[7]);
- if (match[9].rm_so != -1) {
- domain = get_string_arg(line, &match[9]);
- if (domain) {
- upstream_add(ip, port, domain);
- safefree(domain);
- }
- } else {
- upstream_add(ip, port, NULL);
- }
+ if (match[9].rm_so != -1)
+ {
+ domain = get_string_arg (line, &match[9]);
+ if (domain)
+ {
+ upstream_add (ip, port, domain);
+ safefree (domain);
+ }
+ }
+ else
+ {
+ upstream_add (ip, port, NULL);
+ }
- safefree(ip);
+ safefree (ip);
- return 0;
+ return 0;
}
static
-HANDLE_FUNC(handle_upstream_no)
+HANDLE_FUNC (handle_upstream_no)
{
- char *domain;
+ char *domain;
- domain = get_string_arg(line, &match[2]);
- if (!domain) return -1;
+ domain = get_string_arg (line, &match[2]);
+ if (!domain)
+ return -1;
- upstream_add(NULL, 0, domain);
- safefree(domain);
+ upstream_add (NULL, 0, domain);
+ safefree (domain);
- return 0;
+ return 0;
}
#endif
diff --git a/src/conffile.h b/src/conffile.h
index 6393141..3c1b94b 100644
--- a/src/conffile.h
+++ b/src/conffile.h
@@ -21,7 +21,7 @@
#ifndef TINYPROXY_CONFFILE_H
#define TINYPROXY_CONFFILE_H
-extern int config_compile(void);
-extern int config_parse(struct config_s *conf, FILE * f);
+extern int config_compile (void);
+extern int config_parse (struct config_s *conf, FILE * f);
#endif
diff --git a/src/conns.c b/src/conns.c
index 860d7c3..6c04383 100644
--- a/src/conns.c
+++ b/src/conns.c
@@ -31,118 +31,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)
+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 1e1bf45..6c2f365 100644
--- a/src/conns.h
+++ b/src/conns.h
@@ -27,73 +27,76 @@
/*
* Connection Definition
*/
-struct conn_s {
- int client_fd;
- int server_fd;
-
- struct buffer_s *cbuffer;
- struct buffer_s *sbuffer;
-
- /* The request line (first line) from the client */
- char *request_line;
-
- /* 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;
+struct conn_s
+{
+ int client_fd;
+ int server_fd;
+
+ struct buffer_s *cbuffer;
+ struct buffer_s *sbuffer;
+
+ /* The request line (first line) from the client */
+ char *request_line;
+
+ /* 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;
#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
- /*
- * Pointer to upstream proxy.
- */
- struct upstream *upstream_proxy;
+ /*
+ * Pointer to upstream proxy.
+ */
+ struct upstream *upstream_proxy;
};
/*
* 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 void destroy_conn(struct conn_s *connptr);
+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 f0b0aba..fc39b42 100644
--- a/src/daemon.c
+++ b/src/daemon.c
@@ -30,28 +30,28 @@
* program a daemon process.
*/
void
-makedaemon(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(0177);
+ chdir ("/");
+ umask (0177);
#if NDEBUG
- /*
- * When not in debugging mode, close the standard file
- * descriptors.
- */
- close(0);
- close(1);
- close(2);
+ /*
+ * When not in debugging mode, close the standard file
+ * descriptors.
+ */
+ close (0);
+ close (1);
+ close (2);
#endif
}
@@ -60,25 +60,28 @@ 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 e6d33b1..63a679e 100644
--- a/src/daemon.h
+++ b/src/daemon.h
@@ -26,11 +26,11 @@ 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
*/
-extern void makedaemon(void);
+extern void makedaemon (void);
#endif
diff --git a/src/filter.c b/src/filter.c
index 81d274b..06346c3 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -33,10 +33,11 @@
static int err;
-struct filter_list {
- struct filter_list *next;
- char *pat;
- regex_t *cpat;
+struct filter_list
+{
+ struct filter_list *next;
+ char *pat;
+ regex_t *cpat;
};
static struct filter_list *fl = NULL;
@@ -47,171 +48,176 @@ static filter_policy_t default_policy = FILTER_DEFAULT_ALLOW;
* Initializes a linked list of strings containing hosts/urls to be filtered
*/
void
-filter_init(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)
+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)
+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)
+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;
}
/*
* Set the default filtering policy
*/
void
-filter_set_default_policy(filter_policy_t policy)
+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 7c5fcad..17974a6 100644
--- a/src/filter.h
+++ b/src/filter.h
@@ -21,16 +21,17 @@
#ifndef _TINYPROXY_FILTER_H_
#define _TINYPROXY_FILTER_H_
-typedef enum {
- FILTER_DEFAULT_ALLOW,
- FILTER_DEFAULT_DENY,
+typedef enum
+{
+ FILTER_DEFAULT_ALLOW,
+ FILTER_DEFAULT_DENY,
} filter_policy_t;
-extern void filter_init(void);
-extern void filter_destroy(void);
-extern int filter_domain(const char *host);
-extern int filter_url(const char *url);
+extern void filter_init (void);
+extern void filter_destroy (void);
+extern int filter_domain (const char *host);
+extern int filter_url (const char *url);
-extern void filter_set_default_policy(filter_policy_t policy);
+extern void filter_set_default_policy (filter_policy_t policy);
#endif
diff --git a/src/hashmap.c b/src/hashmap.c
index 292c006..764c9a6 100644
--- a/src/hashmap.c
+++ b/src/hashmap.c
@@ -37,23 +37,26 @@
* internal use. It stores the number of buckets the hashmap was created
* with.
*/
-struct hashentry_s {
- char *key;
- void *data;
- size_t len;
+struct hashentry_s
+{
+ char *key;
+ void *data;
+ size_t len;
- struct hashentry_s *prev, *next;
+ struct hashentry_s *prev, *next;
};
-struct hashbucket_s {
- struct hashentry_s *head, *tail;
+struct hashbucket_s
+{
+ struct hashentry_s *head, *tail;
};
-struct hashmap_s {
- unsigned int size;
- hashmap_iter end_iterator;
+struct hashmap_s
+{
+ unsigned int size;
+ hashmap_iter end_iterator;
- struct hashbucket_s *buckets;
+ struct hashbucket_s *buckets;
};
/*
@@ -66,25 +69,26 @@ struct hashmap_s {
* If any of the arguments are invalid a negative number is returned.
*/
static int
-hashfunc(const char *key, unsigned int size)
+hashfunc (const char *key, unsigned int size)
{
- uint32_t hash;
+ uint32_t hash;
- if (key == NULL)
- return -EINVAL;
- if (size == 0)
- return -ERANGE;
+ 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;
+ for (hash = tolower (*key++); *key != '\0'; key++)
+ {
+ uint32_t bit = (hash & 1) ? (1 << (sizeof (uint32_t) - 1)) : 0;
- hash >>= 1;
+ hash >>= 1;
- hash += tolower(*key) + bit;
- }
+ hash += tolower (*key) + bit;
+ }
- /* Keep the hash within the table limits */
- return hash % size;
+ /* Keep the hash within the table limits */
+ return hash % size;
}
/*
@@ -95,28 +99,29 @@ hashfunc(const char *key, unsigned int size)
* NULLs are also returned if memory could not be allocated for hashmap.
*/
hashmap_t
-hashmap_create(unsigned int nbuckets)
+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 +132,27 @@ 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;
}
/*
@@ -156,23 +162,25 @@ delete_hashbucket(struct hashbucket_s *bucket)
* negative if a NULL "map" was supplied
*/
int
-hashmap_delete(hashmap_t map)
+hashmap_delete (hashmap_t map)
{
- unsigned int i;
+ unsigned int i;
- if (map == NULL)
- return -EINVAL;
+ 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,67 +194,69 @@ 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;
-
- data_copy = safemalloc(len);
- if (!data_copy) {
- safefree(key_copy);
- return -ENOMEM;
- }
- memcpy(data_copy, data, len);
-
- 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.
- */
- ptr->next = NULL;
- 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;
+ 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;
+
+ data_copy = safemalloc (len);
+ if (!data_copy)
+ {
+ safefree (key_copy);
+ return -ENOMEM;
+ }
+ memcpy (data_copy, data, len);
+
+ 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.
+ */
+ ptr->next = NULL;
+ 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;
}
/*
@@ -255,17 +265,17 @@ hashmap_insert(hashmap_t map, const char *key, const void *data, size_t len)
* Returns: an negative value upon error.
*/
hashmap_iter
-hashmap_first(hashmap_t map)
+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;
}
/*
@@ -275,18 +285,18 @@ hashmap_first(hashmap_t map)
* 0 otherwise
*/
int
-hashmap_is_end(hashmap_t map, hashmap_iter iter)
+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;
}
/*
@@ -298,37 +308,40 @@ 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;
}
/*
@@ -338,37 +351,41 @@ 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;
}
/*
@@ -379,31 +396,32 @@ hashmap_return_entry(hashmap_t map, hashmap_iter iter, char **key, void **data)
* count found
*/
ssize_t
-hashmap_search(hashmap_t map, const char *key)
+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;
}
/*
@@ -415,30 +433,32 @@ 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;
}
/*
@@ -450,53 +470,55 @@ hashmap_entry_by_key(hashmap_t map, const char *key, void **data)
* positive count of entries deleted
*/
ssize_t
-hashmap_remove(hashmap_t map, const char *key)
+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.
- */
- next = ptr->next;
-
- if (ptr->prev)
- ptr->prev->next = ptr->next;
- if (ptr->next)
- ptr->next->prev = ptr->prev;
-
- if (map->buckets[hash].head == ptr)
- 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;
-
- ptr = next;
- continue;
- }
-
- /* 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;
+ 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)
+ ptr->next->prev = ptr->prev;
+
+ if (map->buckets[hash].head == ptr)
+ 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;
+
+ ptr = next;
+ continue;
+ }
+
+ /* 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;
}
diff --git a/src/hashmap.h b/src/hashmap.h
index 0bde82c..946b619 100644
--- a/src/hashmap.h
+++ b/src/hashmap.h
@@ -23,7 +23,8 @@
/* Allow the use in C++ code. */
#if defined(__cplusplus)
-extern "C" {
+extern "C"
+{
#endif
/*
@@ -31,15 +32,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
@@ -50,15 +51,15 @@ extern "C" {
* 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.
@@ -66,7 +67,7 @@ extern "C" {
* 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
@@ -76,7 +77,7 @@ extern "C" {
* 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.
@@ -86,8 +87,8 @@ extern "C" {
* 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
@@ -97,8 +98,8 @@ extern "C" {
* 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
@@ -108,7 +109,7 @@ extern "C" {
* 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.
@@ -118,9 +119,9 @@ extern "C" {
* 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 2cb8c82..732b285 100644
--- a/src/heap.c
+++ b/src/heap.c
@@ -28,71 +28,72 @@
#include "text.h"
void *
-debugging_calloc(size_t nmemb, size_t size, const char *file,
- unsigned long line)
+debugging_calloc (size_t nmemb, size_t size, const char *file,
+ 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:%zu x %zu} %s:%lu\n", ptr, nmemb, size, file,
- line);
- return ptr;
+ ptr = calloc (nmemb, size);
+ fprintf (stderr, "{calloc: %p:%zu x %zu} %s:%lu\n", ptr, nmemb, size, file,
+ line);
+ return ptr;
}
void *
-debugging_malloc(size_t size, const char *file, unsigned long line)
+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:%zu} %s:%lu\n", ptr, size, file, line);
- return ptr;
+ ptr = malloc (size);
+ fprintf (stderr, "{malloc: %p:%zu} %s:%lu\n", ptr, size, file, line);
+ return ptr;
}
void *
-debugging_realloc(void *ptr, size_t size, const char *file, unsigned long line)
+debugging_realloc (void *ptr, size_t size, const char *file,
+ unsigned long line)
{
- void *newptr;
+ void *newptr;
- assert(size > 0);
+ assert (size > 0);
- newptr = realloc(ptr, size);
- fprintf(stderr, "{realloc: %p -> %p:%zu} %s:%lu\n", ptr, newptr, size,
- file, line);
- return newptr;
+ newptr = realloc (ptr, size);
+ fprintf (stderr, "{realloc: %p -> %p:%zu} %s:%lu\n", ptr, newptr, size,
+ file, line);
+ return newptr;
}
void
-debugging_free(void *ptr, const char *file, unsigned long line)
+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)
+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:%zu} %s:%lu\n", ptr, len, file, line);
- return ptr;
+ fprintf (stderr, "{strdup: %p:%zu} %s:%lu\n", ptr, len, file, line);
+ return ptr;
}
/*
@@ -104,32 +105,32 @@ debugging_strdup(const char *s, const char *file, unsigned long line)
* solution.
*/
void *
-malloc_shared_memory(size_t size)
+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));
- /* Only allow u+rw bits. This may be required for some versions
- * of glibc so that mkstemp() doesn't make us vulnerable.
- */
- umask(0177);
+ /* Only allow u+rw bits. This may be required for some versions
+ * of glibc so that mkstemp() doesn't make us vulnerable.
+ */
+ umask (0177);
- 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;
}
/*
@@ -137,21 +138,21 @@ malloc_shared_memory(size_t size)
* zero.
*/
void *
-calloc_shared_memory(size_t nmemb, size_t size)
+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 2bb0297..272d97c 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -26,15 +26,15 @@
*/
#ifndef NDEBUG
-extern void *debugging_calloc(size_t nmemb, size_t size, const char *file,
- unsigned long line);
-extern void *debugging_malloc(size_t size, const char *file,
- 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);
+extern void *debugging_calloc (size_t nmemb, size_t size, const char *file,
+ unsigned long line);
+extern void *debugging_malloc (size_t size, const char *file,
+ 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);
# define safecalloc(x, y) debugging_calloc(x, y, __FILE__, __LINE__)
# define safemalloc(x) debugging_malloc(x, __FILE__, __LINE__)
@@ -60,7 +60,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/html-error.c b/src/html-error.c
index 1802cde..ac4531b 100644
--- a/src/html-error.c
+++ b/src/html-error.c
@@ -33,77 +33,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)
+add_new_errorpage (char *filepath, unsigned int errornum)
{
- char errornbuf[ERRORNUM_BUFSIZE];
+ 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)
+get_html_file (unsigned int errornum)
{
- hashmap_iter result_iter;
- char errornbuf[ERRORNUM_BUFSIZE];
- char *key;
- static char *val;
+ 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)
+lookup_variable (struct conn_s *connptr, char *varname)
{
- hashmap_iter result_iter;
- char *key;
- static char *data;
+ 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
@@ -112,116 +112,113 @@ 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)
+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);
+ 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)
+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";
+ 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));
+ return (write_message (connptr->client_fd, headers,
+ code, message, PACKAGE, VERSION));
}
/*
* Display an error to the client.
*/
int
-send_http_error_message(struct conn_s *connptr)
+send_http_error_message (struct conn_s *connptr)
{
- char *error_file;
- FILE *infile;
- int ret;
- char *fallback_error =
- "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
- "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n"
- "<html>\n"
- "<head><title>%d %s</title></head>\n"
- "<body>\n"
- "<h1>%s</h1>\n"
- "<p>%s</p>\n"
- "<hr />\n"
- "<p><em>Generated by %s version %s.</em></p>\n"
- "</body>\n"
- "</html>\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"))) {
- char *detail = lookup_variable(connptr, "detail");
- return (write_message(connptr->client_fd, fallback_error,
- connptr->error_number,
- connptr->error_string,
- connptr->error_string,
- detail,
- PACKAGE, VERSION));
- }
-
- ret = send_html_file(infile, connptr);
- fclose(infile);
- return (ret);
+ char *error_file;
+ FILE *infile;
+ int ret;
+ char *fallback_error =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
+ "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n"
+ "<html>\n"
+ "<head><title>%d %s</title></head>\n"
+ "<body>\n"
+ "<h1>%s</h1>\n"
+ "<p>%s</p>\n"
+ "<hr />\n"
+ "<p><em>Generated by %s version %s.</em></p>\n" "</body>\n" "</html>\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")))
+ {
+ char *detail = lookup_variable (connptr, "detail");
+ return (write_message (connptr->client_fd, fallback_error,
+ connptr->error_number,
+ connptr->error_string,
+ connptr->error_string,
+ detail, PACKAGE, VERSION));
+ }
+
+ ret = send_html_file (infile, connptr);
+ fclose (infile);
+ return (ret);
}
/*
@@ -231,16 +228,14 @@ send_http_error_message(struct conn_s *connptr)
#define ERRVAR_BUCKETCOUNT 16
int
-add_error_variable(struct conn_s *connptr, char *key, char *val)
+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);
-
- return hashmap_insert(connptr->error_variables, key, val,
- strlen(val) + 1);
+ if (!connptr->error_variables)
+ if (!(connptr->error_variables = hashmap_create (ERRVAR_BUCKETCOUNT)))
+ return (-1);
+
+ return hashmap_insert (connptr->error_variables, key, val,
+ strlen (val) + 1);
}
#define ADD_VAR_RET(x, y) \
@@ -255,61 +250,63 @@ 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)
+add_standard_vars (struct conn_s *connptr)
{
- char errnobuf[16];
- char timebuf[30];
- time_t global_time;
+ char errnobuf[16];
+ char timebuf[30];
+ time_t global_time;
- snprintf(errnobuf, sizeof errnobuf, "%d", connptr->error_number);
- ADD_VAR_RET("errno", errnobuf);
+ snprintf (errnobuf, sizeof errnobuf, "%d", connptr->error_number);
+ ADD_VAR_RET ("errno", errnobuf);
- ADD_VAR_RET("cause", connptr->error_string);
- ADD_VAR_RET("request", connptr->request_line);
- ADD_VAR_RET("clientip", connptr->client_ip_addr);
- ADD_VAR_RET("clienthost", connptr->client_string_addr);
+ ADD_VAR_RET ("cause", connptr->error_string);
+ ADD_VAR_RET ("request", connptr->request_line);
+ ADD_VAR_RET ("clientip", connptr->client_ip_addr);
+ ADD_VAR_RET ("clienthost", connptr->client_string_addr);
- /* The following value parts are all non-NULL and will
- * trigger warnings in ADD_VAR_RET(), so we use
- * add_error_variable() directly.
- */
+ /* The following value parts are all non-NULL and will
+ * trigger warnings in ADD_VAR_RET(), so we use
+ * add_error_variable() directly.
+ */
- global_time = time(NULL);
- strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT",
- gmtime(&global_time));
- add_error_variable(connptr, "date", timebuf);
+ global_time = time (NULL);
+ strftime (timebuf, sizeof (timebuf), "%a, %d %b %Y %H:%M:%S GMT",
+ gmtime (&global_time));
+ add_error_variable (connptr, "date", timebuf);
- add_error_variable(connptr, "website", "http://tinyproxy.banu.com/");
- add_error_variable(connptr, "version", VERSION);
- add_error_variable(connptr, "package", PACKAGE);
+ add_error_variable (connptr, "website", "http://tinyproxy.banu.com/");
+ add_error_variable (connptr, "version", VERSION);
+ add_error_variable (connptr, "package", PACKAGE);
- return (0);
+ 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/html-error.h b/src/html-error.h
index 2e35b5b..280101c 100644
--- a/src/html-error.h
+++ b/src/html-error.h
@@ -24,13 +24,14 @@
/* Forward declaration */
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 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_http_headers(struct conn_s *connptr, int code, char *message);
-extern int add_standard_vars(struct conn_s *connptr);
+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 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_http_headers (struct conn_s *connptr, int code,
+ char *message);
+extern int add_standard_vars (struct conn_s *connptr);
-#endif /* !TINYPROXY_HTML_ERROR_H */
+#endif /* !TINYPROXY_HTML_ERROR_H */
diff --git a/src/http-message.c b/src/http-message.c
index eadf37f..2cd5a4d 100644
--- a/src/http-message.c
+++ b/src/http-message.c
@@ -30,29 +30,33 @@
* Also, the caller MUST NOT free the memory while the structure is
* 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;
+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;
};
/*
@@ -61,18 +65,18 @@ struct http_message_s {
* number is returned. Useful for if() tests and assert() tests.
*/
static int
-is_http_message_valid(http_message_t msg)
+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 */
@@ -83,32 +87,34 @@ 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;
}
/*
@@ -117,19 +123,19 @@ http_message_create(int response_code, const char *response_string)
* is the responsibility of the caller.
*/
int
-http_message_destroy(http_message_t msg)
+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;
}
/*
@@ -137,135 +143,135 @@ http_message_destroy(http_message_t msg)
* must be a NUL ('\0') terminated C string.
*/
int
-http_message_set_response(http_message_t msg,
- int response_code, const char *response_string)
+http_message_set_response (http_message_t msg,
+ 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;
}
/*
* Send the completed HTTP message via the supplied file descriptor.
*/
int
-http_message_send(http_message_t msg, int fd)
+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 36c5cc3..b83df11 100644
--- a/src/http-message.h
+++ b/src/http-message.h
@@ -58,28 +58,28 @@ typedef struct http_message_s *http_message_t;
#define IS_HTTP_MSG_ERROR(x) (x < 0)
/* Initialize the internal structure of the HTTP message */
-extern http_message_t http_message_create(int response_code,
- const char *response_string);
+extern http_message_t http_message_create (int response_code,
+ const char *response_string);
/* Free up an _internal_ resources */
-extern int http_message_destroy(http_message_t msg);
+extern int http_message_destroy (http_message_t msg);
/*
* Send an HTTP message via the supplied file descriptor. This function
* will add the "Date" header before it's sent.
*/
-extern int http_message_send(http_message_t msg, int fd);
+extern int http_message_send (http_message_t msg, int fd);
/*
* Change the internal state of the HTTP message. Either set the
* body of the message, update the response information, or
* add a new set of headers.
*/
-extern int http_message_set_body(http_message_t msg,
- const char *body, size_t len);
-extern int http_message_set_response(http_message_t msg,
- int response_code,
- const char *response_string);
+extern int http_message_set_body (http_message_t msg,
+ const char *body, size_t len);
+extern int http_message_set_response (http_message_t msg,
+ int response_code,
+ const char *response_string);
/*
* Set the headers for this HTTP message. Each string must be NUL ('\0')
@@ -87,7 +87,7 @@ extern int http_message_set_response(http_message_t msg,
* line-feeds (LF) since they will be included when the http_message is
* sent.
*/
-extern int http_message_add_headers(http_message_t msg,
- char **headers, int num_headers);
+extern int http_message_add_headers (http_message_t msg,
+ 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 84ecb5c..e41c6f6 100644
--- a/src/log.c
+++ b/src/log.c
@@ -29,15 +29,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
@@ -65,165 +65,177 @@ 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;
}
/*
* Close the log file
*/
void
-close_log_file(void)
+close_log_file (void)
{
- close(log_file_fd);
+ close (log_file_fd);
}
/*
* Truncate log file to a zero length.
*/
void
-truncate_log_file(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);
}
/*
* Set the log level for writing to the log file.
*/
void
-set_log_level(int level)
+set_log_level (int level)
{
- log_level = level;
+ log_level = level;
}
/*
* This routine logs messages to either the log file or the syslog function.
*/
void
-log_message(int level, char *fmt, ...)
+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)
- goto out;
- }
+ if (!log_message_storage)
+ {
+ log_message_storage = vector_create ();
+ if (!log_message_storage)
+ goto out;
+ }
- vsnprintf(str, STRING_LENGTH, fmt, args);
+ vsnprintf (str, STRING_LENGTH, fmt, args);
- entry_buffer = safemalloc(strlen(str) + 6);
- if (!entry_buffer)
- goto out;
+ entry_buffer = safemalloc (strlen (str) + 6);
+ if (!entry_buffer)
+ goto out;
- sprintf(entry_buffer, "%d %s", level, str);
- vector_append(log_message_storage, entry_buffer,
- strlen(entry_buffer) + 1);
+ sprintf (entry_buffer, "%d %s", level, str);
+ vector_append (log_message_storage, entry_buffer,
+ strlen (entry_buffer) + 1);
- safefree(entry_buffer);
- goto out;
- }
+ safefree (entry_buffer);
+ goto out;
+ }
#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);
- fsync(log_file_fd);
+ 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
- out:
- va_end(args);
+out:
+ va_end (args);
}
/*
* This needs to send any stored log messages.
*/
void
-send_stored_logs(void)
+send_stored_logs (void)
{
- char *string;
- char *ptr;
+ char *string;
+ char *ptr;
- int level;
+ int level;
- size_t i;
+ size_t 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 118f6f3..a31888c 100644
--- a/src/log.h
+++ b/src/log.h
@@ -87,7 +87,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:
@@ -102,12 +102,12 @@
# define DEBUG2(x, y...) do { } while(0)
#endif
-extern int open_log_file(const char *file);
-extern void close_log_file(void);
-extern void truncate_log_file(void);
+extern int open_log_file (const char *file);
+extern void close_log_file (void);
+extern void truncate_log_file (void);
-extern void log_message(int level, char *fmt, ...);
-extern void set_log_level(int level);
-extern void send_stored_logs(void);
+extern void log_message (int level, char *fmt, ...);
+extern void set_log_level (int level);
+extern void send_stored_logs (void);
#endif
diff --git a/src/network.c b/src/network.c
index 42feac3..7b4bb52 100644
--- a/src/network.c
+++ b/src/network.c
@@ -33,35 +33,37 @@
* again. Keep sending until the buffer has been sent.
*/
ssize_t
-safe_write(int fd, const char *buffer, size_t count)
+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;
}
/*
@@ -69,15 +71,17 @@ safe_write(int fd, const char *buffer, size_t count)
* again.
*/
ssize_t
-safe_read(int fd, char *buffer, size_t count)
+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;
}
/*
@@ -87,47 +91,51 @@ safe_read(int fd, char *buffer, size_t count)
* (although I did fix a memory leak. :)
*/
int
-write_message(int fd, const char *fmt, ...)
+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;
}
/*
@@ -142,103 +150,113 @@ write_message(int fd, const char *fmt, ...)
#define SEGMENT_LEN (512)
#define MAXIMUM_BUFFER_LENGTH (128 * 1024)
ssize_t
-readline(int fd, char **whole_buffer)
+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;
-
- 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;
+ 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;
}
/*
@@ -246,32 +264,35 @@ readline(int fd, char **whole_buffer)
* hex string.
*/
char *
-get_ip_string(struct sockaddr *sa, char *buf, size_t buflen)
+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;
}
/*
@@ -282,41 +303,42 @@ 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 3ba7d6a..b6ddaa6 100644
--- a/src/network.h
+++ b/src/network.h
@@ -21,13 +21,13 @@
#ifndef TINYPROXY_NETWORK_H
#define TINYPROXY_NETWORK_H
-extern ssize_t safe_write(int fd, const char *buffer, size_t count);
-extern ssize_t safe_read(int fd, char *buffer, size_t count);
+extern ssize_t safe_write (int fd, const char *buffer, size_t count);
+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 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 a757c6f..ddf7e20 100644
--- a/src/reqs.c
+++ b/src/reqs.c
@@ -81,20 +81,22 @@ static vector_t ports_allowed_by_connect = NULL;
* it hasn't already by done.
*/
void
-add_connect_port_allowed(int port)
+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));
}
/*
@@ -104,25 +106,26 @@ add_connect_port_allowed(int port)
* 0 if denied
*/
static int
-check_allowed_connect_ports(int port)
+check_allowed_connect_ports (int port)
{
- size_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;
-
- 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 0;
+ size_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;
+
+ 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 0;
}
/*
@@ -131,57 +134,59 @@ check_allowed_connect_ports(int port)
* be freed in another function.
*/
static int
-read_request_line(struct conn_s *connptr)
+read_request_line (struct conn_s *connptr)
{
- 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;
+ 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;
}
/*
* Free all the memory allocated in a request.
*/
static void
-free_request_struct(struct request_s *request)
+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);
}
/*
@@ -189,24 +194,24 @@ free_request_struct(struct request_s *request)
* it off.
*/
static void
-strip_username_password(char *host)
+strip_username_password (char *host)
{
- char *p;
-
- assert(host);
- assert(strlen(host) > 0);
-
- if ((p = strchr(host, '@')) == NULL)
- return;
-
- /*
- * Move the pointer past the "@" and then copy from that point
- * until the NUL to the beginning of the host buffer.
- */
- p++;
- while (*p)
- *host++ = *p++;
- *host = '\0';
+ char *p;
+
+ assert (host);
+ assert (strlen (host) > 0);
+
+ if ((p = strchr (host, '@')) == NULL)
+ return;
+
+ /*
+ * Move the pointer past the "@" and then copy from that point
+ * until the NUL to the beginning of the host buffer.
+ */
+ p++;
+ while (*p)
+ *host++ = *p++;
+ *host = '\0';
}
/*
@@ -214,19 +219,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;
}
/*
@@ -234,70 +239,74 @@ strip_return_port(char *host)
* and FTP (proxied) URLs.
*/
static int
-extract_http_url(const char *url, struct request_s *request)
+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;
}
/*
* Extract the URL from a SSL connection.
*/
static int
-extract_ssl_url(const char *url, struct request_s *request)
+extract_ssl_url (const char *url, struct request_s *request)
{
- request->host = safemalloc(strlen(url) + 1);
- if (!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.");
+ 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;
- }
+ 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;
}
@@ -306,161 +315,183 @@ extract_ssl_url(const char *url, struct request_s *request)
* Add an entry to the upstream list
*/
void
-upstream_add(const char *host, int port, const char *domain)
+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;
}
/*
* Check if a host is in the upstream list
*/
static struct upstream *
-upstream_get(char *host)
+upstream_get (char *host)
{
- struct upstream *up = config.upstream_list;
-
- in_addr_t my_ip = INADDR_NONE;
-
- while (up) {
- if (up->domain) {
- if (strcasecmp(host, up->domain) == 0)
- break; /* exact match */
-
- if (up->domain[0] == '.') {
- char *dot = strchr(host, '.');
-
- if (!dot && !up->domain[1])
- break; /* local host matches "." */
-
- 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 ((my_ip & up->mask) == up->ip)
- break;
- } else {
- break; /* No domain or IP, default upstream */
- }
-
- up = up->next;
- }
-
- 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);
-
- return up;
+ struct upstream *up = config.upstream_list;
+
+ in_addr_t my_ip = INADDR_NONE;
+
+ while (up)
+ {
+ if (up->domain)
+ {
+ if (strcasecmp (host, up->domain) == 0)
+ break; /* exact match */
+
+ if (up->domain[0] == '.')
+ {
+ char *dot = strchr (host, '.');
+
+ if (!dot && !up->domain[1])
+ break; /* local host matches "." */
+
+ 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 ((my_ip & up->mask) == up->ip)
+ break;
+ }
+ else
+ {
+ break; /* No domain or IP, default upstream */
+ }
+
+ up = up->next;
+ }
+
+ 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);
+
+ return up;
}
#endif
@@ -468,22 +499,22 @@ upstream_get(char *host)
* Create a connection for HTTP connections.
*/
static int
-establish_http_connection(struct conn_s *connptr, struct request_s *request)
+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);
}
/*
@@ -497,12 +528,12 @@ establish_http_connection(struct conn_s *connptr, struct request_s *request)
* connection.
*/
static inline int
-send_ssl_response(struct conn_s *connptr)
+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);
}
/*
@@ -510,218 +541,239 @@ send_ssl_response(struct conn_s *connptr)
* build a new request line. Finally connect to the remote server.
*/
static struct request_s *
-process_request(struct conn_s *connptr, hashmap_t hashofheaders)
+process_request (struct conn_s *connptr, hashmap_t hashofheaders)
{
- char *url;
- struct request_s *request;
- int ret;
- 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;
-
- request_len = strlen(connptr->request_line) + 1;
-
- 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);
-
- return NULL;
- }
-
- ret = sscanf(connptr->request_line, "%[^ ] %[^ ] %[^ ]",
- request->method, url, request->protocol);
- if (ret == 2 && !strcasecmp(request->method, "GET")) {
- request->protocol[0] = 0;
-
- /* Indicate that this is a HTTP/0.9 GET request */
- connptr->protocol.major = 0;
- connptr->protocol.minor = 9;
- } else if (ret == 3 && !strncasecmp(request->protocol, "HTTP/", 5)) {
- /*
- * Break apart the protocol and update the connection
- * structure.
- */
- ret = sscanf(request->protocol + 5, "%u.%u",
- &connptr->protocol.major,
- &connptr->protocol.minor);
-
- /*
- * If the conversion doesn't succeed, drop down below and
- * send the error to the user.
- */
- 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;
- }
+ char *url;
+ struct request_s *request;
+ int ret;
+ 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;
+
+ request_len = strlen (connptr->request_line) + 1;
+
+ 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);
+
+ return NULL;
+ }
+
+ ret = sscanf (connptr->request_line, "%[^ ] %[^ ] %[^ ]",
+ request->method, url, request->protocol);
+ if (ret == 2 && !strcasecmp (request->method, "GET"))
+ {
+ request->protocol[0] = 0;
+
+ /* Indicate that this is a HTTP/0.9 GET request */
+ connptr->protocol.major = 0;
+ connptr->protocol.minor = 9;
+ }
+ else if (ret == 3 && !strncasecmp (request->protocol, "HTTP/", 5))
+ {
+ /*
+ * Break apart the protocol and update the connection
+ * structure.
+ */
+ ret = sscanf (request->protocol + 5, "%u.%u",
+ &connptr->protocol.major, &connptr->protocol.minor);
+
+ /*
+ * If the conversion doesn't succeed, drop down below and
+ * send the error to the user.
+ */
+ 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;
+ }
#ifdef REVERSE_SUPPORT
- if (config.reversepath_list != NULL) {
- /*
- * Rewrite the URL based on the reverse path. After calling
- * reverse_rewrite_url "url" can be freed since we either
- * have the newly rewritten URL, or something failed and
- * we'll be closing anyway.
- */
- char *reverse_url;
-
- reverse_url = reverse_rewrite_url(connptr, hashofheaders, url);
- safefree(url);
-
- if (!reverse_url) {
- free_request_struct(request);
- return NULL;
- } else {
- url = reverse_url;
- }
- }
+ if (config.reversepath_list != NULL)
+ {
+ /*
+ * Rewrite the URL based on the reverse path. After calling
+ * reverse_rewrite_url "url" can be freed since we either
+ * have the newly rewritten URL, or something failed and
+ * we'll be closing anyway.
+ */
+ char *reverse_url;
+
+ reverse_url = reverse_rewrite_url (connptr, hashofheaders, url);
+ safefree (url);
+
+ if (!reverse_url)
+ {
+ free_request_struct (request);
+ return NULL;
+ }
+ else
+ {
+ url = reverse_url;
+ }
+ }
#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
- if (!do_transparent_proxy(connptr, hashofheaders, request, &config, url)) {
- safefree(url);
- free_request_struct(request);
- return NULL;
- }
+ if (!do_transparent_proxy
+ (connptr, hashofheaders, request, &config, url))
+ {
+ safefree (url);
+ free_request_struct (request);
+ return NULL;
+ }
#else
- indicate_http_error(connptr, 501, "Not Implemented",
- "detail", "Unknown method or unsupported protocol.",
- "url", url, NULL);
- log_message(LOG_INFO,
- "Unknown method (%s) or protocol (%s)",
- request->method, url);
- safefree(url);
- free_request_struct(request);
- return NULL;
-
+ indicate_http_error (connptr, 501, "Not Implemented",
+ "detail",
+ "Unknown method or unsupported protocol.", "url",
+ url, NULL);
+ log_message (LOG_INFO, "Unknown method (%s) or protocol (%s)",
+ request->method, url);
+ 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;
}
/*
@@ -731,50 +783,52 @@ process_request(struct conn_s *connptr, hashmap_t hashofheaders)
* - rjkaes
*/
static int
-pull_client_data(struct conn_s *connptr, long int length)
+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
@@ -784,13 +838,13 @@ pull_client_data(struct conn_s *connptr, long int length)
* -rjkaes
*/
static inline int
-add_xtinyproxy_header(struct conn_s *connptr)
+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);
+ assert (connptr && connptr->server_fd >= 0);
+ 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.)
@@ -798,82 +852,86 @@ add_xtinyproxy_header(struct conn_s *connptr)
* can be retrieved and manipulated later.
*/
static inline int
-add_header_to_connection(hashmap_t hashofheaders, char *header, size_t len)
+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);
}
/*
* Read all the headers from the stream
*/
static int
-get_all_headers(int fd, hashmap_t hashofheaders)
+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);
+ }
}
/*
@@ -881,53 +939,53 @@ get_all_headers(int fd, hashmap_t hashofheaders)
* and Proxy-Connection headers.
*/
static int
-remove_connection_headers(hashmap_t hashofheaders)
+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;
}
/*
@@ -935,19 +993,18 @@ remove_connection_headers(hashmap_t hashofheaders)
* a negative number.
*/
static long
-get_content_length(hashmap_t hashofheaders)
+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;
}
/*
@@ -958,39 +1015,44 @@ get_content_length(hashmap_t hashofheaders)
* purposes.
*/
static int
-write_via_header(int fd, hashmap_t hashofheaders,
- unsigned int major, unsigned int minor)
+write_via_header (int fd, hashmap_t hashofheaders,
+ 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;
}
/*
@@ -1005,110 +1067,113 @@ write_via_header(int fd, hashmap_t hashofheaders,
* - rjkaes
*/
static int
-process_client_headers(struct conn_s *connptr, hashmap_t hashofheaders)
+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;
}
/*
@@ -1116,184 +1181,192 @@ process_client_headers(struct conn_s *connptr, hashmap_t hashofheaders)
* server.
*/
static int
-process_server_headers(struct conn_s *connptr)
+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. */
- 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;
- }
-
- /*
- * At this point we've received the response line and all the
- * headers. However, if this is a simple HTTP/0.9 request we
- * CAN NOT send any of that information back to the client.
- * Instead we'll free all the memory and return.
- */
- if (connptr->protocol.major < 1) {
- hashmap_delete(hashofheaders);
- safefree(response_line);
- return 0;
- }
-
- /* 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;
+ /* 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;
+ }
+
+ /*
+ * At this point we've received the response line and all the
+ * headers. However, if this is a simple HTTP/0.9 request we
+ * CAN NOT send any of that information back to the client.
+ * Instead we'll free all the memory and return.
+ */
+ if (connptr->protocol.major < 1)
+ {
+ hashmap_delete (hashofheaders);
+ safefree (response_line);
+ return 0;
+ }
+
+ /* 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;
#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;
}
/*
@@ -1305,186 +1378,204 @@ process_server_headers(struct conn_s *connptr)
* - rjkaes
*/
static void
-relay_connection(struct conn_s *connptr)
+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;
}
/*
* Establish a connection to the upstream proxy server.
*/
static int
-connect_to_upstream(struct conn_s *connptr, struct request_s *request)
+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
}
@@ -1498,168 +1589,190 @@ connect_to_upstream(struct conn_s *connptr, struct request_s *request)
* - rjkaes
*/
void
-handle_connection(int fd)
+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);
- }
-
- send_error:
- free_request_struct(request);
-
- if (process_client_headers(connptr, hashofheaders) < 0) {
- update_stats(STAT_BADCONN);
- if (!connptr->error_variables) {
- hashmap_delete(hashofheaders);
- destroy_conn(connptr);
- return;
- }
- }
- 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;
+ 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);
+
+ if (process_client_headers (connptr, hashofheaders) < 0)
+ {
+ update_stats (STAT_BADCONN);
+ if (!connptr->error_variables)
+ {
+ hashmap_delete (hashofheaders);
+ destroy_conn (connptr);
+ return;
+ }
+ }
+ 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;
}
diff --git a/src/reqs.h b/src/reqs.h
index de8730e..39501fc 100644
--- a/src/reqs.h
+++ b/src/reqs.h
@@ -34,18 +34,19 @@
/*
* This structure holds the information pulled from a URL request.
*/
-struct request_s {
- char *method;
- char *protocol;
+struct request_s
+{
+ char *method;
+ char *protocol;
- char *host;
- uint16_t port;
+ char *host;
+ uint16_t port;
- char *path;
+ char *path;
};
-extern void handle_connection(int fd);
-extern void add_connect_port_allowed(int port);
-extern void upstream_add(const char *host, int port, const char *domain);
+extern void handle_connection (int fd);
+extern void add_connect_port_allowed (int port);
+extern void upstream_add (const char *host, int port, const char *domain);
#endif
diff --git a/src/reverse-proxy.c b/src/reverse-proxy.c
index 9915540..2ed98b4 100644
--- a/src/reverse-proxy.c
+++ b/src/reverse-proxy.c
@@ -30,128 +30,132 @@
* Add entry to the reversepath list
*/
void
-reversepath_add(const char *path, const char *url)
+reversepath_add (const char *path, const char *url)
{
- struct reversepath *reverse;
-
- 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 (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 (!path)
- reverse->path = safestrdup("/");
- else
- reverse->path = safestrdup(path);
-
- reverse->url = safestrdup(url);
-
- reverse->next = config.reversepath_list;
- config.reversepath_list = reverse;
-
- log_message(LOG_INFO,
- "Added reverse proxy rule: %s -> %s", reverse->path,
- reverse->url);
+ struct reversepath *reverse;
+
+ 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 (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 (!path)
+ reverse->path = safestrdup ("/");
+ else
+ reverse->path = safestrdup (path);
+
+ reverse->url = safestrdup (url);
+
+ reverse->next = config.reversepath_list;
+ config.reversepath_list = reverse;
+
+ log_message (LOG_INFO,
+ "Added reverse proxy rule: %s -> %s", reverse->path,
+ reverse->url);
}
/*
* Check if a request url is in the reversepath list
*/
struct reversepath *
-reversepath_get(char *url)
+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;
}
/*
* Rewrite the URL for reverse proxying.
*/
char *
-reverse_rewrite_url(struct conn_s *connptr, hashmap_t hashofheaders, char *url)
+reverse_rewrite_url (struct conn_s *connptr, hashmap_t hashofheaders,
+ char *url)
{
- char *rewrite_url = NULL;
- char *cookie = NULL;
- char *cookieval;
- struct reversepath *reverse;
-
- /* 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);
- return NULL;
- }
-
- log_message(LOG_CONN, "Rewriting URL: %s -> %s", url, rewrite_url);
-
- /* Store reverse path so that the magical tracking cookie can be set */
- if (config.reversemagic)
- connptr->reversepath = safestrdup(reverse->path);
-
- return rewrite_url;
+ char *rewrite_url = NULL;
+ char *cookie = NULL;
+ char *cookieval;
+ struct reversepath *reverse;
+
+ /* 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);
+ return NULL;
+ }
+
+ log_message (LOG_CONN, "Rewriting URL: %s -> %s", url, rewrite_url);
+
+ /* Store reverse path so that the magical tracking cookie can be set */
+ if (config.reversemagic)
+ connptr->reversepath = safestrdup (reverse->path);
+
+ return rewrite_url;
}
diff --git a/src/reverse-proxy.h b/src/reverse-proxy.h
index 2ad8522..2bb8a16 100644
--- a/src/reverse-proxy.h
+++ b/src/reverse-proxy.h
@@ -23,17 +23,18 @@
#include "conns.h"
-struct reversepath {
- struct reversepath *next;
- char *path;
- char *url;
+struct reversepath
+{
+ struct reversepath *next;
+ char *path;
+ char *url;
};
#define REVERSE_COOKIE "yummy_magical_cookie"
-extern void reversepath_add(const char *path, const char *url);
-extern struct reversepath *reversepath_get(char *url);
-extern char *reverse_rewrite_url(struct conn_s *connptr,
- hashmap_t hashofheaders, char *url);
+extern void reversepath_add (const char *path, const char *url);
+extern struct reversepath *reversepath_get (char *url);
+extern char *reverse_rewrite_url (struct conn_s *connptr,
+ hashmap_t hashofheaders, char *url);
#endif
diff --git a/src/sock.c b/src/sock.c
index d4e961c..ad06d97 100644
--- a/src/sock.c
+++ b/src/sock.c
@@ -39,34 +39,36 @@
* 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;
}
/*
@@ -75,91 +77,97 @@ 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;
}
/*
* Set the socket to non blocking -rjkaes
*/
int
-socket_nonblocking(int sock)
+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);
}
/*
* Set the socket to blocking -rjkaes
*/
int
-socket_blocking(int sock)
+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);
}
/*
@@ -169,95 +177,101 @@ 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;
- socklen_t salen = sizeof sa;
+ struct sockaddr_storage sa;
+ socklen_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 3a0f967..5eac10b 100644
--- a/src/sock.h
+++ b/src/sock.h
@@ -28,13 +28,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 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 1b958ce..25a053d 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -33,12 +33,13 @@
#include "stats.h"
#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;
+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;
};
static struct stat_s *stats;
@@ -47,83 +48,82 @@ static struct stat_s *stats;
* Initialize the statistics information to zero.
*/
void
-init_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));
}
/*
* Display the statics of the tinyproxy server.
*/
int
-showstats(struct conn_s *connptr)
+showstats (struct conn_s *connptr)
{
- static char *msg =
- "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
- "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n"
- "<html>\n"
- "<head><title>%s version %s run-time statistics</title></head>\n"
- "<body>\n"
- "<h1>%s version %s run-time statistics</h1>\n"
- "<p>\n"
- "Number of open connections: %lu<br />\n"
- "Number of requests: %lu<br />\n"
- "Number of bad connections: %lu<br />\n"
- "Number of denied connections: %lu<br />\n"
- "Number of refused connections due to high load: %lu\n"
- "</p>\n"
- "<hr />\n"
- "<p><em>Generated by %s version %s.</em></p>\n"
- "</body>\n"
- "</html>\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,
- PACKAGE, VERSION);
-
- 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, "deniedconns", denied);
- add_error_variable(connptr, "refusedconns", refused);
- add_standard_vars(connptr);
- send_http_headers(connptr, 200, "Statistic requested");
- send_html_file(statfile, connptr);
- fclose(statfile);
-
- return 0;
+ static char *msg =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
+ "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n"
+ "<html>\n"
+ "<head><title>%s version %s run-time statistics</title></head>\n"
+ "<body>\n"
+ "<h1>%s version %s run-time statistics</h1>\n"
+ "<p>\n"
+ "Number of open connections: %lu<br />\n"
+ "Number of requests: %lu<br />\n"
+ "Number of bad connections: %lu<br />\n"
+ "Number of denied connections: %lu<br />\n"
+ "Number of refused connections due to high load: %lu\n"
+ "</p>\n"
+ "<hr />\n"
+ "<p><em>Generated by %s version %s.</em></p>\n" "</body>\n" "</html>\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, PACKAGE, VERSION);
+
+ 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, "deniedconns", denied);
+ add_error_variable (connptr, "refusedconns", refused);
+ add_standard_vars (connptr);
+ send_http_headers (connptr, 200, "Statistic requested");
+ send_html_file (statfile, connptr);
+ fclose (statfile);
+
+ return 0;
}
/*
@@ -131,28 +131,29 @@ showstats(struct conn_s *connptr)
* stats.h
*/
int
-update_stats(status_t update_level)
+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 b7a8218..a75d92e 100644
--- a/src/stats.h
+++ b/src/stats.h
@@ -26,19 +26,20 @@
/*
* 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 */
+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 */
} status_t;
/*
* Public API to the statistics for tinyproxy
*/
-extern void init_stats(void);
-extern int showstats(struct conn_s *connptr);
-extern int update_stats(status_t update_level);
+extern void init_stats (void);
+extern int showstats (struct conn_s *connptr);
+extern int update_stats (status_t update_level);
#endif
diff --git a/src/text.c b/src/text.c
index e091e00..322983f 100644
--- a/src/text.c
+++ b/src/text.c
@@ -33,18 +33,18 @@
* destination buffer.
*/
size_t
-strlcpy(char *dst, const char *src, size_t size)
+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
@@ -56,20 +56,21 @@ strlcpy(char *dst, const char *src, size_t size)
* length.
*/
size_t
-strlcat(char *dst, const char *src, size_t size)
+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
@@ -83,30 +84,31 @@ strlcat(char *dst, const char *src, size_t size)
* negative return value indicates an error.
*/
ssize_t
-chomp(char *buffer, size_t length)
+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 4074efa..0beb9b1 100644
--- a/src/text.h
+++ b/src/text.h
@@ -22,13 +22,13 @@
#define TINYPROXY_TEXT_H
#ifndef HAVE_STRLCAT
-extern size_t strlcat(char *dst, const char *src, size_t size);
-#endif /* HAVE_STRLCAT */
+extern size_t strlcat (char *dst, const char *src, size_t size);
+#endif /* HAVE_STRLCAT */
#ifndef HAVE_STRLCPY
-extern size_t strlcpy(char *dst, const char *src, size_t size);
-#endif /* HAVE_STRLCPY */
+extern size_t strlcpy (char *dst, const char *src, size_t size);
+#endif /* HAVE_STRLCPY */
-extern ssize_t chomp(char *buffer, size_t length);
+extern ssize_t chomp (char *buffer, size_t length);
#endif
diff --git a/src/tinyproxy.c b/src/tinyproxy.c
index 03ca9b5..6708743 100644
--- a/src/tinyproxy.c
+++ b/src/tinyproxy.c
@@ -41,60 +41,61 @@
#include "stats.h"
#include "utils.h"
-RETSIGTYPE takesig(int sig);
+RETSIGTYPE takesig (int sig);
/*
* Global Structures
*/
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
*/
RETSIGTYPE
-takesig(int sig)
+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;
}
/*
* Display the version information for the user.
*/
static void
-display_version(void)
+display_version (void)
{
- printf("%s %s (%s)\n", PACKAGE, VERSION, TARGET_SYSTEM);
+ printf ("%s %s (%s)\n", PACKAGE, VERSION, TARGET_SYSTEM);
}
/*
* Display the copyright and license for this program.
*/
static void
-display_license(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\
@@ -119,10 +120,10 @@ display_license(void)
* Display usage to the user.
*/
static void
-display_usage(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\
@@ -130,319 +131,344 @@ 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");
-#endif /* TRANSPARENT_PROXY */
+ 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 */
}
static int
get_id (char *str)
{
- char *tstr;
+ char *tstr;
- if (str == NULL)
- return -1;
+ if (str == NULL)
+ return -1;
- tstr = str;
- while (*tstr != 0) {
- if (!isdigit(*tstr))
- return -1;
- tstr++;
- }
+ tstr = str;
+ while (*tstr != 0)
+ {
+ if (!isdigit (*tstr))
+ return -1;
+ tstr++;
+ }
- return atoi(str);
+ return atoi (str);
}
int
-main(int argc, char **argv)
+main (int argc, char **argv)
{
- int optch;
- unsigned int godaemon = TRUE; /* boolean */
- struct passwd *thisuser = NULL;
- struct group *thisgroup = NULL;
- FILE *config_file;
-
- /* Only allow u+rw bits. This may be required for some versions
- * of glibc so that mkstemp() doesn't make us vulnerable.
- */
- umask(0177);
-
- /* 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);
- }
- if (config_compile() || config_parse(&config, config_file)) {
- fprintf(stderr,
- "Unable to parse configuration file. Not starting.\n");
- exit(EX_SOFTWARE);
- }
- fclose(config_file);
-
- /*
- * Write to a user supplied log file if it's defined. This
- * will override using the syslog even if syslog is defined.
- */
- if (config.logf_name) {
- if (open_log_file(config.logf_name) < 0) {
- fprintf(stderr,
- "%s: Could not create log file.\n", argv[0]);
- exit(EX_SOFTWARE);
- }
- 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 {
- 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.user) {
- 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);
- }
+ int optch;
+ unsigned int godaemon = TRUE; /* boolean */
+ struct passwd *thisuser = NULL;
+ struct group *thisgroup = NULL;
+ FILE *config_file;
+
+ /* Only allow u+rw bits. This may be required for some versions
+ * of glibc so that mkstemp() doesn't make us vulnerable.
+ */
+ umask (0177);
+
+ /* 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);
+ }
+ if (config_compile () || config_parse (&config, config_file))
+ {
+ fprintf (stderr,
+ "Unable to parse configuration file. Not starting.\n");
+ exit (EX_SOFTWARE);
+ }
+ fclose (config_file);
+
+ /*
+ * Write to a user supplied log file if it's defined. This
+ * will override using the syslog even if syslog is defined.
+ */
+ if (config.logf_name)
+ {
+ if (open_log_file (config.logf_name) < 0)
+ {
+ fprintf (stderr, "%s: Could not create log file.\n", argv[0]);
+ exit (EX_SOFTWARE);
+ }
+ 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
+ {
+ 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.user)
+ {
+ 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) {
- int gid = get_id(config.group);
- if (gid < 0) {
- thisgroup = getgrnam(config.group);
- if (!thisgroup) {
- fprintf(stderr,
- "%s: Unable to find "
- "group \"%s\".\n",
- argv[0], config.group);
- exit(EX_NOUSER);
- }
- gid = thisgroup->gr_gid;
- }
- if (setgid(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.user && strlen(config.user) > 0) {
- int uid = get_id(config.user);
- if (uid < 0) {
- thisuser = getpwnam(config.user);
- if (!thisuser) {
- fprintf(stderr,
- "%s: Unable to find "
- "user \"%s\".",
- argv[0], config.user);
- exit(EX_NOUSER);
- }
- uid = thisuser->pw_uid;
- }
- if (setuid(uid) < 0) {
- fprintf(stderr,
- "%s: Unable to change to user \"%s\".",
- argv[0], config.user);
- exit(EX_CANTCREAT);
- }
- log_message(LOG_INFO, "Now running as user \"%s\".",
- config.user);
- }
- } 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)
+ {
+ int gid = get_id (config.group);
+ if (gid < 0)
+ {
+ thisgroup = getgrnam (config.group);
+ if (!thisgroup)
+ {
+ fprintf (stderr,
+ "%s: Unable to find "
+ "group \"%s\".\n", argv[0], config.group);
+ exit (EX_NOUSER);
+ }
+ gid = thisgroup->gr_gid;
+ }
+ if (setgid (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.user && strlen (config.user) > 0)
+ {
+ int uid = get_id (config.user);
+ if (uid < 0)
+ {
+ thisuser = getpwnam (config.user);
+ if (!thisuser)
+ {
+ fprintf (stderr,
+ "%s: Unable to find "
+ "user \"%s\".", argv[0], config.user);
+ exit (EX_NOUSER);
+ }
+ uid = thisuser->pw_uid;
+ }
+ if (setuid (uid) < 0)
+ {
+ fprintf (stderr,
+ "%s: Unable to change to user \"%s\".",
+ argv[0], config.user);
+ exit (EX_CANTCREAT);
+ }
+ log_message (LOG_INFO, "Now running as user \"%s\".", config.user);
+ }
+ }
+ 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 88ed541..fe73da7 100644
--- a/src/tinyproxy.h
+++ b/src/tinyproxy.h
@@ -26,82 +26,84 @@
#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
+{
+ struct upstream *next;
+ char *domain; /* optional */
+ char *host;
+ int port;
+ in_addr_t ip, mask;
};
/*
* 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 *user;
- char *group;
- char *ipAddr;
+struct config_s
+{
+ char *logf_name;
+ char *config_file;
+ unsigned int syslog; /* boolean */
+ int port;
+ char *stathost;
+ unsigned int quit; /* boolean */
+ char *user;
+ 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/transparent-proxy.c b/src/transparent-proxy.c
index 5bffa31..b089030 100644
--- a/src/transparent-proxy.c
+++ b/src/transparent-proxy.c
@@ -36,86 +36,86 @@
* Build a URL from parts.
*/
static int
-build_url(char **url, const char *host, int port, const char *path)
+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);
}
int
-do_transparent_proxy(struct conn_s *connptr, hashmap_t hashofheaders,
- struct request_s *request, struct config_s *conf, char *url)
+do_transparent_proxy (struct conn_s *connptr, hashmap_t hashofheaders,
+ struct request_s *request, struct config_s *conf,
+ char *url)
{
- socklen_t 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);
- return 0;
- }
- 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 (conf->ipAddr && strcmp(request->host, conf->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);
- return 0;
- }
+ socklen_t length;
+ char *data;
- return 1;
+ 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);
+ return 0;
+ }
+ 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 (conf->ipAddr && strcmp (request->host, conf->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);
+ return 0;
+ }
+
+ return 1;
}
diff --git a/src/transparent-proxy.h b/src/transparent-proxy.h
index 37cc54d..09a7777 100644
--- a/src/transparent-proxy.h
+++ b/src/transparent-proxy.h
@@ -29,9 +29,10 @@
#include "hashmap.h"
#include "reqs.h"
-extern int do_transparent_proxy(struct conn_s *connptr,
- hashmap_t hashofheaders, struct request_s *request,
- struct config_s *config, char *url);
+extern int do_transparent_proxy (struct conn_s *connptr,
+ hashmap_t hashofheaders,
+ struct request_s *request,
+ struct config_s *config, char *url);
#endif
diff --git a/src/utils.c b/src/utils.c
index 0f4acaa..5064555 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -34,175 +34,183 @@
* Build the data for a complete HTTP & HTML message for the client.
*/
int
-send_http_message(struct conn_s *connptr, int http_code,
- const char *error_title, const char *message)
+send_http_message (struct conn_s *connptr, int http_code,
+ 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;
}
/*
* Safely creates filename and returns the low-level file descriptor.
*/
int
-create_file_safely(const char *filename, unsigned int truncate_file)
+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;
}
/*
* Write the PID of the program to the specified file.
*/
int
-pidfile_create(const char *filename)
+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 81172e2..784a2ac 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -27,10 +27,11 @@
*/
struct conn_s;
-extern int send_http_message(struct conn_s *connptr, int http_code,
- const char *error_title, const char *message);
+extern int send_http_message (struct conn_s *connptr, int http_code,
+ 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);
+extern int pidfile_create (const char *path);
+extern int create_file_safely (const char *filename,
+ unsigned int truncate_file);
#endif
diff --git a/src/vector.c b/src/vector.c
index e9ca586..a68fddc 100644
--- a/src/vector.c
+++ b/src/vector.c
@@ -33,17 +33,19 @@
* vector_s stores a pointer to the first vector (vector[0]) and a
* count of the number of entries (or how long the vector is.)
*/
-struct vectorentry_s {
- void *data;
- size_t len;
+struct vectorentry_s
+{
+ 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;
+struct vector_s
+{
+ size_t num_entries;
+ struct vectorentry_s *head;
+ struct vectorentry_s *tail;
};
/*
@@ -54,18 +56,18 @@ struct vector_s {
* vector.
*/
vector_t
-vector_create(void)
+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;
+ vector->num_entries = 0;
+ vector->head = vector->tail = NULL;
- return vector;
+ return vector;
}
/*
@@ -75,25 +77,26 @@ vector_create(void)
* negative if a NULL vector is supplied
*/
int
-vector_delete(vector_t vector)
+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;
}
/*
@@ -110,44 +113,48 @@ vector_delete(vector_t vector)
#define INSERT_APPEND 1
static int
-vector_insert(vector_t vector, void *data, ssize_t len, int pos)
+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;
}
/*
@@ -156,15 +163,15 @@ vector_insert(vector_t vector, void *data, ssize_t len, int pos)
* arguments.
*/
int
-vector_append(vector_t vector, void *data, ssize_t len)
+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)
+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 +182,27 @@ 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 >= vector->num_entries)
- return NULL;
+ if (!vector || 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;
}
/*
@@ -204,10 +212,10 @@ vector_getentry(vector_t vector, size_t pos, size_t * size)
* positive length of vector otherwise
*/
ssize_t
-vector_length(vector_t vector)
+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 ad40bf0..f319cad 100644
--- a/src/vector.h
+++ b/src/vector.h
@@ -23,7 +23,8 @@
/* Allow the use in C++ code. */
#if defined(__cplusplus)
-extern "C" {
+extern "C"
+{
#endif
/*
@@ -31,14 +32,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
@@ -48,8 +49,8 @@ extern "C" {
* 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
@@ -67,8 +68,7 @@ extern "C" {
* 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.
@@ -76,9 +76,9 @@ extern "C" {
* 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 */