Reformat code to GNU coding style

This is a commit which simply ran all C source code files
through GNU indent. No other modifications were made.
master
Mukund Sivaraman 2008-12-01 15:01:11 +00:00
parent 448c19077c
commit a257703e59
47 changed files with 4909 additions and 4566 deletions

157
src/acl.c
View File

@ -33,19 +33,23 @@
/* Define how long an IPv6 address is in bytes (128 bits, 16 bytes) */ /* Define how long an IPv6 address is in bytes (128 bits, 16 bytes) */
#define IPV6_LEN 16 #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 * 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 * whether it's an ALLOW or DENY entry, and also whether it's a string
* entry (like a domain name) or an IP entry. * entry (like a domain name) or an IP entry.
*/ */
struct acl_s { struct acl_s
{
acl_access_t access; acl_access_t access;
enum acl_type type; enum acl_type type;
union { union
{
char *string; char *string;
struct { struct
{
unsigned char octet[IPV6_LEN]; unsigned char octet[IPV6_LEN];
unsigned char mask[IPV6_LEN]; unsigned char mask[IPV6_LEN];
} ip; } ip;
@ -67,19 +71,19 @@ static vector_t access_list = NULL;
* *
*/ */
inline static int 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; unsigned int i;
long int mask; long int mask;
char *endptr; char *endptr;
errno = 0; /* to distinguish success/failure after call */ errno = 0; /* to distinguish success/failure after call */
mask = strtol(bitmask_string, &endptr, 10); mask = strtol (bitmask_string, &endptr, 10);
/* check for various conversion errors */ /* check for various conversion errors */
if ((errno == ERANGE && (mask == LONG_MIN || mask == LONG_MAX)) if ((errno == ERANGE && (mask == LONG_MIN || mask == LONG_MAX))
|| (errno != 0 && mask == 0) || (errno != 0 && mask == 0) || (endptr == bitmask_string))
|| (endptr == bitmask_string))
return -1; return -1;
/* valid range for a bit mask */ /* valid range for a bit mask */
@ -87,16 +91,20 @@ fill_netmask_array(char *bitmask_string, unsigned char array[], unsigned int len
return -1; return -1;
/* we have a valid range to fill in the array */ /* we have a valid range to fill in the array */
for (i = 0; i != len; ++i) { for (i = 0; i != len; ++i)
if (mask >= 8) { {
if (mask >= 8)
{
array[i] = 0xff; array[i] = 0xff;
mask -= 8; mask -= 8;
} }
else if (mask > 0) { else if (mask > 0)
array[i] = (unsigned char)(0xff << (8 - mask)); {
array[i] = (unsigned char) (0xff << (8 - mask));
mask = 0; mask = 0;
} }
else { else
{
array[i] = 0; array[i] = 0;
} }
} }
@ -115,22 +123,23 @@ fill_netmask_array(char *bitmask_string, unsigned char array[], unsigned int len
* 0 otherwise. * 0 otherwise.
*/ */
int int
insert_acl(char *location, acl_access_t access_type) insert_acl (char *location, acl_access_t access_type)
{ {
struct acl_s acl; struct acl_s acl;
int ret; int ret;
char *p, ip_dst[IPV6_LEN]; char *p, ip_dst[IPV6_LEN];
assert(location != NULL); assert (location != NULL);
/* /*
* If the access list has not been set up, create it. * If the access list has not been set up, create it.
*/ */
if (!access_list) { if (!access_list)
access_list = vector_create(); {
if (!access_list) { access_list = vector_create ();
log_message(LOG_ERR, if (!access_list)
"Unable to allocate memory for access list"); {
log_message (LOG_ERR, "Unable to allocate memory for access list");
return -1; return -1;
} }
} }
@ -138,40 +147,47 @@ insert_acl(char *location, acl_access_t access_type)
/* /*
* Start populating the access control structure. * Start populating the access control structure.
*/ */
memset(&acl, 0, sizeof(struct acl_s)); memset (&acl, 0, sizeof (struct acl_s));
acl.access = access_type; acl.access = access_type;
/* /*
* Check for a valid IP address (the simplest case) first. * Check for a valid IP address (the simplest case) first.
*/ */
if (full_inet_pton(location, ip_dst) > 0) { if (full_inet_pton (location, ip_dst) > 0)
{
acl.type = ACL_NUMERIC; acl.type = ACL_NUMERIC;
memcpy(acl.address.ip.octet, ip_dst, IPV6_LEN); memcpy (acl.address.ip.octet, ip_dst, IPV6_LEN);
memset(acl.address.ip.mask, 0xff, IPV6_LEN); memset (acl.address.ip.mask, 0xff, IPV6_LEN);
} else { }
else
{
/* /*
* At this point we're either a hostname or an * At this point we're either a hostname or an
* IP address with a slash. * IP address with a slash.
*/ */
p = strchr(location, '/'); p = strchr (location, '/');
if (p != NULL) { if (p != NULL)
{
/* /*
* We have a slash, so it's intended to be an * We have a slash, so it's intended to be an
* IP address with mask * IP address with mask
*/ */
*p = '\0'; *p = '\0';
if (full_inet_pton(location, ip_dst) <= 0) if (full_inet_pton (location, ip_dst) <= 0)
return -1; return -1;
acl.type = ACL_NUMERIC; acl.type = ACL_NUMERIC;
memcpy(acl.address.ip.octet, ip_dst, IPV6_LEN); memcpy (acl.address.ip.octet, ip_dst, IPV6_LEN);
if (fill_netmask_array(p + 1, &(acl.address.ip.mask[0]), IPV6_LEN) < 0) if (fill_netmask_array (p + 1, &(acl.address.ip.mask[0]), IPV6_LEN)
< 0)
return -1; return -1;
} else { }
else
{
/* In all likelihood a string */ /* In all likelihood a string */
acl.type = ACL_STRING; acl.type = ACL_STRING;
acl.address.string = safestrdup(location); acl.address.string = safestrdup (location);
if (!acl.address.string) if (!acl.address.string)
return -1; return -1;
} }
@ -180,8 +196,8 @@ insert_acl(char *location, acl_access_t access_type)
/* /*
* Add the entry and then clean up. * Add the entry and then clean up.
*/ */
ret = vector_append(access_list, &acl, sizeof(struct acl_s)); ret = vector_append (access_list, &acl, sizeof (struct acl_s));
safefree(acl.address.string); safefree (acl.address.string);
return ret; return ret;
} }
@ -195,7 +211,7 @@ insert_acl(char *location, acl_access_t access_type)
* -1 if no tests match, so skip * -1 if no tests match, so skip
*/ */
static int static int
acl_string_processing(struct acl_s *acl, acl_string_processing (struct acl_s *acl,
const char *ip_address, const char *string_address) const char *ip_address, const char *string_address)
{ {
int match; int match;
@ -203,36 +219,41 @@ acl_string_processing(struct acl_s *acl,
size_t test_length, match_length; size_t test_length, match_length;
char ipbuf[512]; char ipbuf[512];
assert(acl && acl->type == ACL_STRING); assert (acl && acl->type == ACL_STRING);
assert(ip_address && strlen(ip_address) > 0); assert (ip_address && strlen (ip_address) > 0);
assert(string_address && strlen(string_address) > 0); assert (string_address && strlen (string_address) > 0);
/* /*
* If the first character of the ACL string is a period, we need to * 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 * do a string based test only; otherwise, we can do a reverse
* lookup test as well. * lookup test as well.
*/ */
if (acl->address.string[0] != '.') { if (acl->address.string[0] != '.')
memset(&hints, 0, sizeof(struct addrinfo)); {
memset (&hints, 0, sizeof (struct addrinfo));
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(acl->address.string, NULL, &hints, &res) != 0) if (getaddrinfo (acl->address.string, NULL, &hints, &res) != 0)
goto STRING_TEST; goto STRING_TEST;
ressave = res; ressave = res;
match = FALSE; match = FALSE;
do { do
get_ip_string(res->ai_addr, ipbuf, sizeof(ipbuf)); {
if (strcmp(ip_address, ipbuf) == 0) { get_ip_string (res->ai_addr, ipbuf, sizeof (ipbuf));
if (strcmp (ip_address, ipbuf) == 0)
{
match = TRUE; match = TRUE;
break; break;
} }
} while ((res = res->ai_next) != NULL); }
while ((res = res->ai_next) != NULL);
freeaddrinfo(ressave); freeaddrinfo (ressave);
if (match) { if (match)
{
if (acl->access == ACL_DENY) if (acl->access == ACL_DENY)
return 0; return 0;
else else
@ -240,9 +261,9 @@ acl_string_processing(struct acl_s *acl,
} }
} }
STRING_TEST: STRING_TEST:
test_length = strlen(string_address); test_length = strlen (string_address);
match_length = strlen(acl->address.string); match_length = strlen (acl->address.string);
/* /*
* If the string length is shorter than AC string, return a -1 so * If the string length is shorter than AC string, return a -1 so
@ -253,7 +274,8 @@ acl_string_processing(struct acl_s *acl,
if (strcasecmp if (strcasecmp
(string_address + (test_length - match_length), (string_address + (test_length - match_length),
acl->address.string) == 0) { acl->address.string) == 0)
{
if (acl->access == ACL_DENY) if (acl->access == ACL_DENY)
return 0; return 0;
else else
@ -273,18 +295,19 @@ acl_string_processing(struct acl_s *acl,
* -1 neither allowed nor denied. * -1 neither allowed nor denied.
*/ */
static int 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; uint8_t addr[IPV6_LEN], x, y;
int i; int i;
assert(acl && acl->type == ACL_NUMERIC); assert (acl && acl->type == ACL_NUMERIC);
assert(ip && strlen(ip) > 0); assert (ip && strlen (ip) > 0);
if (full_inet_pton(ip, &addr) <= 0) if (full_inet_pton (ip, &addr) <= 0)
return -1; return -1;
for (i = 0; i != IPV6_LEN; ++i) { for (i = 0; i != IPV6_LEN; ++i)
{
x = addr[i] & acl->address.ip.mask[i]; x = addr[i] & acl->address.ip.mask[i];
y = acl->address.ip.octet[i] & acl->address.ip.mask[i]; y = acl->address.ip.octet[i] & acl->address.ip.mask[i];
@ -305,15 +328,15 @@ check_numeric_acl(const struct acl_s *acl, const char *ip)
* 0 if denied * 0 if denied
*/ */
int 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; struct acl_s *acl;
int perm; int perm;
size_t i; size_t i;
assert(fd >= 0); assert (fd >= 0);
assert(ip != NULL); assert (ip != NULL);
assert(host != NULL); assert (host != NULL);
/* /*
* If there is no access list allow everything. * If there is no access list allow everything.
@ -321,17 +344,19 @@ check_acl(int fd, const char *ip, const char *host)
if (!access_list) if (!access_list)
return 1; return 1;
for (i = 0; i != vector_length(access_list); ++i) { for (i = 0; i != vector_length (access_list); ++i)
acl = vector_getentry(access_list, i, NULL); {
switch (acl->type) { acl = vector_getentry (access_list, i, NULL);
switch (acl->type)
{
case ACL_STRING: case ACL_STRING:
perm = acl_string_processing(acl, ip, host); perm = acl_string_processing (acl, ip, host);
break; break;
case ACL_NUMERIC: case ACL_NUMERIC:
if (ip[0] == '\0') if (ip[0] == '\0')
continue; continue;
perm = check_numeric_acl(acl, ip); perm = check_numeric_acl (acl, ip);
break; break;
} }
@ -348,7 +373,7 @@ check_acl(int fd, const char *ip, const char *host)
/* /*
* Deny all connections by default. * Deny all connections by default.
*/ */
log_message(LOG_NOTICE, "Unauthorized connection from \"%s\" [%s].", log_message (LOG_NOTICE, "Unauthorized connection from \"%s\" [%s].",
host, ip); host, ip);
return 0; return 0;
} }

View File

@ -21,10 +21,11 @@
#ifndef TINYPROXY_ACL_H #ifndef TINYPROXY_ACL_H
#define 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 insert_acl (char *location, acl_access_t access_type);
extern int check_acl(int fd, const char *ip_address, extern int check_acl (int fd, const char *ip_address,
const char *string_address); const char *string_address);
#endif #endif

View File

@ -30,7 +30,7 @@
static hashmap_t anonymous_map = NULL; static hashmap_t anonymous_map = NULL;
short int 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. * zero if the string was found, zero if it wasn't and negative upon error.
*/ */
int int
anonymous_search(char *s) anonymous_search (char *s)
{ {
assert(s != NULL); assert (s != NULL);
assert(anonymous_map != 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. * successful.
*/ */
int int
anonymous_insert(char *s) anonymous_insert (char *s)
{ {
char data = 1; char data = 1;
assert(s != NULL); assert (s != NULL);
if (!anonymous_map) { if (!anonymous_map)
anonymous_map = hashmap_create(32); {
anonymous_map = hashmap_create (32);
if (!anonymous_map) if (!anonymous_map)
return -1; return -1;
} }
if (hashmap_search(anonymous_map, s) > 0) { if (hashmap_search (anonymous_map, s) > 0)
{
/* The key was already found, so return a positive number. */ /* The key was already found, so return a positive number. */
return 0; return 0;
} }
/* Insert the new key */ /* Insert the new key */
return hashmap_insert(anonymous_map, s, &data, sizeof(data)); return hashmap_insert (anonymous_map, s, &data, sizeof (data));
} }

View File

@ -21,8 +21,8 @@
#ifndef _TINYPROXY_ANONYMOUS_H_ #ifndef _TINYPROXY_ANONYMOUS_H_
#define _TINYPROXY_ANONYMOUS_H_ #define _TINYPROXY_ANONYMOUS_H_
extern short int is_anonymous_enabled(void); extern short int is_anonymous_enabled (void);
extern int anonymous_search(char *s); extern int anonymous_search (char *s);
extern int anonymous_insert(char *s); extern int anonymous_insert (char *s);
#endif #endif

View File

@ -34,7 +34,8 @@
#define BUFFER_HEAD(x) (x)->head #define BUFFER_HEAD(x) (x)->head
#define BUFFER_TAIL(x) (x)->tail #define BUFFER_TAIL(x) (x)->tail
struct bufline_s { struct bufline_s
{
unsigned char *string; /* the actual string of data */ unsigned char *string; /* the actual string of data */
struct bufline_s *next; /* pointer to next in linked list */ struct bufline_s *next; /* pointer to next in linked list */
size_t length; /* length of the string of data */ size_t length; /* length of the string of data */
@ -45,7 +46,8 @@ struct bufline_s {
* The buffer structure points to the beginning and end of the buffer list * The buffer structure points to the beginning and end of the buffer list
* (and includes the total size) * (and includes the total size)
*/ */
struct buffer_s { struct buffer_s
{
struct bufline_s *head; /* top of the buffer */ struct bufline_s *head; /* top of the buffer */
struct bufline_s *tail; /* bottom of the buffer */ struct bufline_s *tail; /* bottom of the buffer */
size_t size; /* total size of the buffer */ size_t size; /* total size of the buffer */
@ -57,22 +59,23 @@ struct buffer_s {
* data buffer on the heap, delete it because you now have TWO copies. * data buffer on the heap, delete it because you now have TWO copies.
*/ */
static struct bufline_s * 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 (data != NULL);
assert(length > 0); assert (length > 0);
if (!(newline = safemalloc(sizeof(struct bufline_s)))) if (!(newline = safemalloc (sizeof (struct bufline_s))))
return NULL; return NULL;
if (!(newline->string = safemalloc(length))) { if (!(newline->string = safemalloc (length)))
safefree(newline); {
safefree (newline);
return NULL; return NULL;
} }
memcpy(newline->string, data, length); memcpy (newline->string, data, length);
newline->next = NULL; newline->next = NULL;
newline->length = length; newline->length = length;
@ -87,28 +90,28 @@ makenewline(unsigned char *data, size_t length)
* Free the allocated buffer line * Free the allocated buffer line
*/ */
static void static void
free_line(struct bufline_s *line) free_line (struct bufline_s *line)
{ {
assert(line != NULL); assert (line != NULL);
if (!line) if (!line)
return; return;
if (line->string) if (line->string)
safefree(line->string); safefree (line->string);
safefree(line); safefree (line);
} }
/* /*
* Create a new buffer * Create a new buffer
*/ */
struct buffer_s * struct buffer_s *
new_buffer(void) new_buffer (void)
{ {
struct buffer_s *buffptr; struct buffer_s *buffptr;
if (!(buffptr = safemalloc(sizeof(struct buffer_s)))) if (!(buffptr = safemalloc (sizeof (struct buffer_s))))
return NULL; return NULL;
/* /*
@ -116,7 +119,7 @@ new_buffer(void)
* pointers to NULL since they can't possibly point anywhere at the * pointers to NULL since they can't possibly point anywhere at the
* moment. * moment.
*/ */
BUFFER_HEAD(buffptr) = BUFFER_TAIL(buffptr) = NULL; BUFFER_HEAD (buffptr) = BUFFER_TAIL (buffptr) = NULL;
buffptr->size = 0; buffptr->size = 0;
return buffptr; return buffptr;
@ -126,26 +129,27 @@ new_buffer(void)
* Delete all the lines in the buffer and the buffer itself * Delete all the lines in the buffer and the buffer itself
*/ */
void 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)) { while (BUFFER_HEAD (buffptr))
next = BUFFER_HEAD(buffptr)->next; {
free_line(BUFFER_HEAD(buffptr)); next = 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. * Return the current size of the buffer.
*/ */
size_t size_t
buffer_size(struct buffer_s *buffptr) buffer_size (struct buffer_s *buffptr)
{ {
return buffptr->size; return buffptr->size;
} }
@ -154,34 +158,35 @@ buffer_size(struct buffer_s *buffptr)
* Push a new line on to the end of the buffer. * Push a new line on to the end of the buffer.
*/ */
int 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; struct bufline_s *newline;
assert(buffptr != NULL); assert (buffptr != NULL);
assert(data != NULL); assert (data != NULL);
assert(length > 0); assert (length > 0);
/* /*
* Sanity check here. A buffer with a non-NULL head pointer must * Sanity check here. A buffer with a non-NULL head pointer must
* have a size greater than zero, and vice-versa. * have a size greater than zero, and vice-versa.
*/ */
if (BUFFER_HEAD(buffptr) == NULL) if (BUFFER_HEAD (buffptr) == NULL)
assert(buffptr->size == 0); assert (buffptr->size == 0);
else else
assert(buffptr->size > 0); assert (buffptr->size > 0);
/* /*
* Make a new line so we can add it to the buffer. * Make a new line so we can add it to the buffer.
*/ */
if (!(newline = makenewline(data, length))) if (!(newline = makenewline (data, length)))
return -1; return -1;
if (buffptr->size == 0) if (buffptr->size == 0)
BUFFER_HEAD(buffptr) = BUFFER_TAIL(buffptr) = newline; BUFFER_HEAD (buffptr) = BUFFER_TAIL (buffptr) = newline;
else { else
BUFFER_TAIL(buffptr)->next = newline; {
BUFFER_TAIL(buffptr) = newline; BUFFER_TAIL (buffptr)->next = newline;
BUFFER_TAIL (buffptr) = newline;
} }
buffptr->size += length; buffptr->size += length;
@ -193,15 +198,15 @@ add_to_buffer(struct buffer_s *buffptr, unsigned char *data, size_t length)
* Remove the first line from the top of the buffer * Remove the first line from the top of the buffer
*/ */
static struct bufline_s * 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 (buffptr != NULL);
assert(BUFFER_HEAD(buffptr) != NULL); assert (BUFFER_HEAD (buffptr) != NULL);
line = BUFFER_HEAD(buffptr); line = BUFFER_HEAD (buffptr);
BUFFER_HEAD(buffptr) = line->next; BUFFER_HEAD (buffptr) = line->next;
buffptr->size -= line->length; buffptr->size -= line->length;
@ -214,13 +219,13 @@ remove_from_buffer(struct buffer_s *buffptr)
*/ */
#define READ_BUFFER_SIZE (1024 * 2) #define READ_BUFFER_SIZE (1024 * 2)
ssize_t ssize_t
read_buffer(int fd, struct buffer_s * buffptr) read_buffer (int fd, struct buffer_s * buffptr)
{ {
ssize_t bytesin; ssize_t bytesin;
unsigned char *buffer; unsigned char *buffer;
assert(fd >= 0); assert (fd >= 0);
assert(buffptr != NULL); assert (buffptr != NULL);
/* /*
* Don't allow the buffer to grow larger than MAXBUFFSIZE * Don't allow the buffer to grow larger than MAXBUFFSIZE
@ -228,25 +233,33 @@ read_buffer(int fd, struct buffer_s * buffptr)
if (buffptr->size >= MAXBUFFSIZE) if (buffptr->size >= MAXBUFFSIZE)
return 0; return 0;
buffer = safemalloc(READ_BUFFER_SIZE); buffer = safemalloc (READ_BUFFER_SIZE);
if (!buffer) { if (!buffer)
{
return -ENOMEM; return -ENOMEM;
} }
bytesin = read(fd, buffer, READ_BUFFER_SIZE); bytesin = read (fd, buffer, READ_BUFFER_SIZE);
if (bytesin > 0) { if (bytesin > 0)
if (add_to_buffer(buffptr, buffer, bytesin) < 0) { {
log_message(LOG_ERR, if (add_to_buffer (buffptr, buffer, bytesin) < 0)
"readbuff: add_to_buffer() error."); {
log_message (LOG_ERR, "readbuff: add_to_buffer() error.");
bytesin = -1; bytesin = -1;
} }
} else { }
if (bytesin == 0) { else
{
if (bytesin == 0)
{
/* connection was closed by client */ /* connection was closed by client */
bytesin = -1; bytesin = -1;
} else { }
switch (errno) { else
{
switch (errno)
{
#ifdef EWOULDBLOCK #ifdef EWOULDBLOCK
case EWOULDBLOCK: case EWOULDBLOCK:
#else #else
@ -258,16 +271,16 @@ read_buffer(int fd, struct buffer_s * buffptr)
bytesin = 0; bytesin = 0;
break; break;
default: default:
log_message(LOG_ERR, log_message (LOG_ERR,
"readbuff: recv() error \"%s\" on file descriptor %d", "readbuff: recv() error \"%s\" on file descriptor %d",
strerror(errno), fd); strerror (errno), fd);
bytesin = -1; bytesin = -1;
break; break;
} }
} }
} }
safefree(buffer); safefree (buffer);
return bytesin; return bytesin;
} }
@ -276,33 +289,37 @@ read_buffer(int fd, struct buffer_s * buffptr)
* Takes a connection and returns the number of bytes written. * Takes a connection and returns the number of bytes written.
*/ */
ssize_t ssize_t
write_buffer(int fd, struct buffer_s * buffptr) write_buffer (int fd, struct buffer_s * buffptr)
{ {
ssize_t bytessent; ssize_t bytessent;
struct bufline_s *line; struct bufline_s *line;
assert(fd >= 0); assert (fd >= 0);
assert(buffptr != NULL); assert (buffptr != NULL);
if (buffptr->size == 0) if (buffptr->size == 0)
return 0; return 0;
/* Sanity check. It would be bad to be using a NULL pointer! */ /* Sanity check. It would be bad to be using a NULL pointer! */
assert(BUFFER_HEAD(buffptr) != NULL); assert (BUFFER_HEAD (buffptr) != NULL);
line = BUFFER_HEAD(buffptr); line = BUFFER_HEAD (buffptr);
bytessent = bytessent =
send(fd, line->string + line->pos, line->length - line->pos, send (fd, line->string + line->pos, line->length - line->pos,
MSG_NOSIGNAL); MSG_NOSIGNAL);
if (bytessent >= 0) { if (bytessent >= 0)
{
/* bytes sent, adjust buffer */ /* bytes sent, adjust buffer */
line->pos += bytessent; line->pos += bytessent;
if (line->pos == line->length) if (line->pos == line->length)
free_line(remove_from_buffer(buffptr)); free_line (remove_from_buffer (buffptr));
return bytessent; return bytessent;
} else { }
switch (errno) { else
{
switch (errno)
{
#ifdef EWOULDBLOCK #ifdef EWOULDBLOCK
case EWOULDBLOCK: case EWOULDBLOCK:
#else #else
@ -314,14 +331,14 @@ write_buffer(int fd, struct buffer_s * buffptr)
return 0; return 0;
case ENOBUFS: case ENOBUFS:
case ENOMEM: case ENOMEM:
log_message(LOG_ERR, log_message (LOG_ERR,
"writebuff: write() error [NOBUFS/NOMEM] \"%s\" on file descriptor %d", "writebuff: write() error [NOBUFS/NOMEM] \"%s\" on file descriptor %d",
strerror(errno), fd); strerror (errno), fd);
return 0; return 0;
default: default:
log_message(LOG_ERR, log_message (LOG_ERR,
"writebuff: write() error \"%s\" on file descriptor %d", "writebuff: write() error \"%s\" on file descriptor %d",
strerror(errno), fd); strerror (errno), fd);
return -1; return -1;
} }
} }

View File

@ -24,17 +24,17 @@
/* Forward declaration */ /* Forward declaration */
struct buffer_s; struct buffer_s;
extern struct buffer_s *new_buffer(void); extern struct buffer_s *new_buffer (void);
extern void delete_buffer(struct buffer_s *buffptr); extern void delete_buffer (struct buffer_s *buffptr);
extern size_t buffer_size(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. * 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, extern int add_to_buffer (struct buffer_s *buffptr, unsigned char *data,
size_t length); size_t length);
extern ssize_t read_buffer(int fd, struct buffer_s *buffptr); extern ssize_t read_buffer (int fd, struct buffer_s *buffptr);
extern ssize_t write_buffer(int fd, struct buffer_s *buffptr); extern ssize_t write_buffer (int fd, struct buffer_s *buffptr);
#endif /* __BUFFER_H_ */ #endif /* __BUFFER_H_ */

View File

@ -37,8 +37,10 @@ static socklen_t addrlen;
/* /*
* Stores the internal data needed for each child (connection) * Stores the internal data needed for each child (connection)
*/ */
enum child_status_t { T_EMPTY, T_WAITING, T_CONNECTED }; enum child_status_t
struct child_s { { T_EMPTY, T_WAITING, T_CONNECTED };
struct child_s
{
pid_t tid; pid_t tid;
unsigned int connects; unsigned int connects;
enum child_status_t status; enum child_status_t status;
@ -50,7 +52,8 @@ struct child_s {
*/ */
static struct child_s *child_ptr; static struct child_s *child_ptr;
static struct child_config_s { static struct child_config_s
{
int maxclients, maxrequestsperchild; int maxclients, maxrequestsperchild;
int maxspareservers, minspareservers, startservers; int maxspareservers, minspareservers, startservers;
} child_config; } child_config;
@ -74,17 +77,17 @@ static struct flock lock_it, unlock_it;
static int lock_fd = -1; static int lock_fd = -1;
static void 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 /* Only allow u+rw bits. This may be required for some versions
* of glibc so that mkstemp() doesn't make us vulnerable. * of glibc so that mkstemp() doesn't make us vulnerable.
*/ */
umask(0177); umask (0177);
lock_fd = mkstemp(lock_file); lock_fd = mkstemp (lock_file);
unlink(lock_file); unlink (lock_file);
lock_it.l_type = F_WRLCK; lock_it.l_type = F_WRLCK;
lock_it.l_whence = SEEK_SET; lock_it.l_whence = SEEK_SET;
@ -98,11 +101,12 @@ _child_lock_init(void)
} }
static void static void
_child_lock_wait(void) _child_lock_wait (void)
{ {
int rc; int rc;
while ((rc = fcntl(lock_fd, F_SETLKW, &lock_it)) < 0) { while ((rc = fcntl (lock_fd, F_SETLKW, &lock_it)) < 0)
{
if (errno == EINTR) if (errno == EINTR)
continue; continue;
else else
@ -111,9 +115,9 @@ _child_lock_wait(void)
} }
static void static void
_child_lock_release(void) _child_lock_release (void)
{ {
if (fcntl(lock_fd, F_SETLKW, &unlock_it) < 0) if (fcntl (lock_fd, F_SETLKW, &unlock_it) < 0)
return; return;
} }
@ -138,9 +142,10 @@ _child_lock_release(void)
* Set the configuration values for the various child related settings. * Set the configuration values for the various child related settings.
*/ */
short int short int
child_configure(child_config_t type, int val) child_configure (child_config_t type, int val)
{ {
switch (type) { switch (type)
{
case CHILD_MAXCLIENTS: case CHILD_MAXCLIENTS:
child_config.maxclients = val; child_config.maxclients = val;
break; break;
@ -157,7 +162,7 @@ child_configure(child_config_t type, int val)
child_config.maxrequestsperchild = val; child_config.maxrequestsperchild = val;
break; break;
default: default:
DEBUG2("Invalid type (%d)", type); DEBUG2 ("Invalid type (%d)", type);
return -1; return -1;
} }
@ -168,96 +173,102 @@ child_configure(child_config_t type, int val)
* This is the main (per child) loop. * This is the main (per child) loop.
*/ */
static void static void
child_main(struct child_s *ptr) child_main (struct child_s *ptr)
{ {
int connfd; int connfd;
struct sockaddr *cliaddr; struct sockaddr *cliaddr;
socklen_t clilen; socklen_t clilen;
cliaddr = safemalloc(addrlen); cliaddr = safemalloc (addrlen);
if (!cliaddr) { if (!cliaddr)
log_message(LOG_CRIT, {
"Could not allocate memory for child address."); log_message (LOG_CRIT, "Could not allocate memory for child address.");
exit(0); exit (0);
} }
ptr->connects = 0; ptr->connects = 0;
while (!config.quit) { while (!config.quit)
{
ptr->status = T_WAITING; ptr->status = T_WAITING;
clilen = addrlen; clilen = addrlen;
connfd = accept(listenfd, cliaddr, &clilen); connfd = accept (listenfd, cliaddr, &clilen);
#ifndef NDEBUG #ifndef NDEBUG
/* /*
* Enable the TINYPROXY_DEBUG environment variable if you * Enable the TINYPROXY_DEBUG environment variable if you
* want to use the GDB debugger. * want to use the GDB debugger.
*/ */
if (getenv("TINYPROXY_DEBUG")) { if (getenv ("TINYPROXY_DEBUG"))
{
/* Pause for 10 seconds to allow us to connect debugger */ /* Pause for 10 seconds to allow us to connect debugger */
fprintf(stderr, fprintf (stderr,
"Process has accepted connection: %ld\n", "Process has accepted connection: %ld\n",
(long int)ptr->tid); (long int) ptr->tid);
sleep(10); sleep (10);
fprintf(stderr, "Continuing process: %ld\n", fprintf (stderr, "Continuing process: %ld\n", (long int) ptr->tid);
(long int)ptr->tid);
} }
#endif #endif
/* /*
* Make sure no error occurred... * Make sure no error occurred...
*/ */
if (connfd < 0) { if (connfd < 0)
log_message(LOG_ERR, {
log_message (LOG_ERR,
"Accept returned an error (%s) ... retrying.", "Accept returned an error (%s) ... retrying.",
strerror(errno)); strerror (errno));
continue; continue;
} }
ptr->status = T_CONNECTED; ptr->status = T_CONNECTED;
SERVER_DEC(); SERVER_DEC ();
handle_connection(connfd); handle_connection (connfd);
ptr->connects++; ptr->connects++;
if (child_config.maxrequestsperchild != 0) { if (child_config.maxrequestsperchild != 0)
DEBUG2("%u connections so far...", ptr->connects); {
DEBUG2 ("%u connections so far...", ptr->connects);
if (ptr->connects == child_config.maxrequestsperchild) { if (ptr->connects == child_config.maxrequestsperchild)
log_message(LOG_NOTICE, {
log_message (LOG_NOTICE,
"Child has reached MaxRequestsPerChild (%u). Killing child.", "Child has reached MaxRequestsPerChild (%u). Killing child.",
ptr->connects); ptr->connects);
break; break;
} }
} }
SERVER_COUNT_LOCK(); SERVER_COUNT_LOCK ();
if (*servers_waiting > child_config.maxspareservers) { if (*servers_waiting > child_config.maxspareservers)
{
/* /*
* There are too many spare children, kill ourself * There are too many spare children, kill ourself
* off. * off.
*/ */
log_message(LOG_NOTICE, log_message (LOG_NOTICE,
"Waiting servers (%d) exceeds MaxSpareServers (%d). Killing child.", "Waiting servers (%d) exceeds MaxSpareServers (%d). Killing child.",
*servers_waiting, *servers_waiting, child_config.maxspareservers);
child_config.maxspareservers); SERVER_COUNT_UNLOCK ();
SERVER_COUNT_UNLOCK();
break; break;
} else { }
SERVER_COUNT_UNLOCK(); else
{
SERVER_COUNT_UNLOCK ();
} }
SERVER_INC(); SERVER_INC ();
} }
ptr->status = T_EMPTY; ptr->status = T_EMPTY;
safefree(cliaddr); safefree (cliaddr);
exit(0); exit (0);
} }
/* /*
@ -265,21 +276,21 @@ child_main(struct child_s *ptr)
* child_main() function. * child_main() function.
*/ */
static pid_t 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) if ((pid = fork ()) > 0)
return pid; /* parent */ return pid; /* parent */
/* /*
* Reset the SIGNALS so that the child can be reaped. * Reset the SIGNALS so that the child can be reaped.
*/ */
set_signal_handler(SIGCHLD, SIG_DFL); set_signal_handler (SIGCHLD, SIG_DFL);
set_signal_handler(SIGTERM, SIG_DFL); set_signal_handler (SIGTERM, SIG_DFL);
set_signal_handler(SIGHUP, SIG_DFL); set_signal_handler (SIGHUP, SIG_DFL);
child_main(ptr); /* never returns */ child_main (ptr); /* never returns */
return -1; return -1;
} }
@ -287,7 +298,7 @@ child_make(struct child_s *ptr)
* Create a pool of children to handle incoming connections * Create a pool of children to handle incoming connections
*/ */
short int short int
child_pool_create(void) child_pool_create (void)
{ {
unsigned int i; unsigned int i;
@ -296,28 +307,31 @@ child_pool_create(void)
* variable determines the size of the array created for children * variable determines the size of the array created for children
* later on. * later on.
*/ */
if (child_config.maxclients == 0) { if (child_config.maxclients == 0)
log_message(LOG_ERR, {
log_message (LOG_ERR,
"child_pool_create: \"MaxClients\" must be greater than zero."); "child_pool_create: \"MaxClients\" must be greater than zero.");
return -1; return -1;
} }
if (child_config.startservers == 0) { if (child_config.startservers == 0)
log_message(LOG_ERR, {
log_message (LOG_ERR,
"child_pool_create: \"StartServers\" must be greater than zero."); "child_pool_create: \"StartServers\" must be greater than zero.");
return -1; return -1;
} }
child_ptr = calloc_shared_memory(child_config.maxclients, child_ptr = calloc_shared_memory (child_config.maxclients,
sizeof(struct child_s)); sizeof (struct child_s));
if (!child_ptr) { if (!child_ptr)
log_message(LOG_ERR, "Could not allocate memory for children."); {
log_message (LOG_ERR, "Could not allocate memory for children.");
return -1; return -1;
} }
servers_waiting = malloc_shared_memory(sizeof(unsigned int)); servers_waiting = malloc_shared_memory (sizeof (unsigned int));
if (servers_waiting == MAP_FAILED) { if (servers_waiting == MAP_FAILED)
log_message(LOG_ERR, {
"Could not allocate memory for child counting."); log_message (LOG_ERR, "Could not allocate memory for child counting.");
return -1; return -1;
} }
*servers_waiting = 0; *servers_waiting = 0;
@ -326,41 +340,47 @@ child_pool_create(void)
* Create a "locking" file for use around the servers_waiting * Create a "locking" file for use around the servers_waiting
* variable. * variable.
*/ */
_child_lock_init(); _child_lock_init ();
if (child_config.startservers > child_config.maxclients) { if (child_config.startservers > child_config.maxclients)
log_message(LOG_WARNING, {
log_message (LOG_WARNING,
"Can not start more than \"MaxClients\" servers. Starting %u servers instead.", "Can not start more than \"MaxClients\" servers. Starting %u servers instead.",
child_config.maxclients); child_config.maxclients);
child_config.startservers = child_config.maxclients; child_config.startservers = child_config.maxclients;
} }
for (i = 0; i != child_config.maxclients; i++) { for (i = 0; i != child_config.maxclients; i++)
{
child_ptr[i].status = T_EMPTY; child_ptr[i].status = T_EMPTY;
child_ptr[i].connects = 0; child_ptr[i].connects = 0;
} }
for (i = 0; i != child_config.startservers; i++) { for (i = 0; i != child_config.startservers; i++)
DEBUG2("Trying to create child %d of %d", i + 1, {
DEBUG2 ("Trying to create child %d of %d", i + 1,
child_config.startservers); child_config.startservers);
child_ptr[i].status = T_WAITING; child_ptr[i].status = T_WAITING;
child_ptr[i].tid = child_make(&child_ptr[i]); child_ptr[i].tid = child_make (&child_ptr[i]);
if (child_ptr[i].tid < 0) { if (child_ptr[i].tid < 0)
log_message(LOG_WARNING, {
log_message (LOG_WARNING,
"Could not create child number %d of %d", "Could not create child number %d of %d",
i, child_config.startservers); i, child_config.startservers);
return -1; return -1;
} else { }
log_message(LOG_INFO, else
{
log_message (LOG_INFO,
"Creating child number %d of %d ...", "Creating child number %d of %d ...",
i + 1, child_config.startservers); i + 1, child_config.startservers);
SERVER_INC(); SERVER_INC ();
} }
} }
log_message(LOG_INFO, "Finished creating all children."); log_message (LOG_INFO, "Finished creating all children.");
return 0; return 0;
} }
@ -370,58 +390,64 @@ child_pool_create(void)
* servers. It monitors this at least once a second. * servers. It monitors this at least once a second.
*/ */
void void
child_main_loop(void) child_main_loop (void)
{ {
unsigned int i; unsigned int i;
while (1) { while (1)
{
if (config.quit) if (config.quit)
return; return;
/* If there are not enough spare servers, create more */ /* If there are not enough spare servers, create more */
SERVER_COUNT_LOCK(); SERVER_COUNT_LOCK ();
if (*servers_waiting < child_config.minspareservers) { if (*servers_waiting < child_config.minspareservers)
log_message(LOG_NOTICE, {
log_message (LOG_NOTICE,
"Waiting servers (%d) is less than MinSpareServers (%d). Creating new child.", "Waiting servers (%d) is less than MinSpareServers (%d). Creating new child.",
*servers_waiting, *servers_waiting, child_config.minspareservers);
child_config.minspareservers);
SERVER_COUNT_UNLOCK(); SERVER_COUNT_UNLOCK ();
for (i = 0; i != child_config.maxclients; i++) { for (i = 0; i != child_config.maxclients; i++)
if (child_ptr[i].status == T_EMPTY) { {
if (child_ptr[i].status == T_EMPTY)
{
child_ptr[i].status = T_WAITING; child_ptr[i].status = T_WAITING;
child_ptr[i].tid = child_ptr[i].tid = child_make (&child_ptr[i]);
child_make(&child_ptr[i]); if (child_ptr[i].tid < 0)
if (child_ptr[i].tid < 0) { {
log_message(LOG_NOTICE, log_message (LOG_NOTICE, "Could not create child");
"Could not create child");
child_ptr[i].status = T_EMPTY; child_ptr[i].status = T_EMPTY;
break; break;
} }
SERVER_INC(); SERVER_INC ();
break; break;
} }
} }
} else { }
SERVER_COUNT_UNLOCK(); else
{
SERVER_COUNT_UNLOCK ();
} }
sleep(5); sleep (5);
/* Handle log rotation if it was requested */ /* Handle log rotation if it was requested */
if (received_sighup) { if (received_sighup)
truncate_log_file(); {
truncate_log_file ();
#ifdef FILTER_ENABLE #ifdef FILTER_ENABLE
if (config.filter) { if (config.filter)
filter_destroy(); {
filter_init(); filter_destroy ();
filter_init ();
} }
log_message(LOG_NOTICE, "Re-reading filter file."); log_message (LOG_NOTICE, "Re-reading filter file.");
#endif /* FILTER_ENABLE */ #endif /* FILTER_ENABLE */
received_sighup = FALSE; received_sighup = FALSE;
@ -433,25 +459,26 @@ child_main_loop(void)
* Go through all the non-empty children and cancel them. * Go through all the non-empty children and cancel them.
*/ */
void void
child_kill_children(void) child_kill_children (void)
{ {
unsigned int i; unsigned int i;
for (i = 0; i != child_config.maxclients; i++) { for (i = 0; i != child_config.maxclients; i++)
{
if (child_ptr[i].status != T_EMPTY) if (child_ptr[i].status != T_EMPTY)
kill(child_ptr[i].tid, SIGTERM); kill (child_ptr[i].tid, SIGTERM);
} }
} }
int int
child_listening_sock(uint16_t port) child_listening_sock (uint16_t port)
{ {
listenfd = listen_sock(port, &addrlen); listenfd = listen_sock (port, &addrlen);
return listenfd; return listenfd;
} }
void void
child_close_sock(void) child_close_sock (void)
{ {
close(listenfd); close (listenfd);
} }

View File

@ -21,7 +21,8 @@
#ifndef TINYPROXY_CHILD_H #ifndef TINYPROXY_CHILD_H
#define TINYPROXY_CHILD_H #define TINYPROXY_CHILD_H
typedef enum { typedef enum
{
CHILD_MAXCLIENTS, CHILD_MAXCLIENTS,
CHILD_MAXSPARESERVERS, CHILD_MAXSPARESERVERS,
CHILD_MINSPARESERVERS, CHILD_MINSPARESERVERS,
@ -29,12 +30,12 @@ typedef enum {
CHILD_MAXREQUESTSPERCHILD CHILD_MAXREQUESTSPERCHILD
} child_config_t; } child_config_t;
extern short int child_pool_create(void); extern short int child_pool_create (void);
extern int child_listening_sock(uint16_t port); extern int child_listening_sock (uint16_t port);
extern void child_close_sock(void); extern void child_close_sock (void);
extern void child_main_loop(void); extern void child_main_loop (void);
extern void child_kill_children(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 #endif

View File

@ -66,7 +66,8 @@
* All configuration handling functions are REQUIRED to be defined * All configuration handling functions are REQUIRED to be defined
* with the same function template as below. * 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 * 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. * to be in-scope before the big structure below.
*/ */
static static
HANDLE_FUNC(handle_nop) HANDLE_FUNC (handle_nop)
{ {
return 0; return 0;
} /* do nothing function */ } /* do nothing function */
static HANDLE_FUNC(handle_allow); static HANDLE_FUNC (handle_allow);
static HANDLE_FUNC(handle_anonymous); static HANDLE_FUNC (handle_anonymous);
static HANDLE_FUNC(handle_bind); static HANDLE_FUNC (handle_bind);
static HANDLE_FUNC(handle_bindsame); static HANDLE_FUNC (handle_bindsame);
static HANDLE_FUNC(handle_connectport); static HANDLE_FUNC (handle_connectport);
static HANDLE_FUNC(handle_defaulterrorfile); static HANDLE_FUNC (handle_defaulterrorfile);
static HANDLE_FUNC(handle_deny); static HANDLE_FUNC (handle_deny);
static HANDLE_FUNC(handle_errorfile); static HANDLE_FUNC (handle_errorfile);
#ifdef FILTER_ENABLE #ifdef FILTER_ENABLE
static HANDLE_FUNC(handle_filter); static HANDLE_FUNC (handle_filter);
static HANDLE_FUNC(handle_filtercasesensitive); static HANDLE_FUNC (handle_filtercasesensitive);
static HANDLE_FUNC(handle_filterdefaultdeny); static HANDLE_FUNC (handle_filterdefaultdeny);
static HANDLE_FUNC(handle_filterextended); static HANDLE_FUNC (handle_filterextended);
static HANDLE_FUNC(handle_filterurls); static HANDLE_FUNC (handle_filterurls);
#endif #endif
static HANDLE_FUNC(handle_group); static HANDLE_FUNC (handle_group);
static HANDLE_FUNC(handle_listen); static HANDLE_FUNC (handle_listen);
static HANDLE_FUNC(handle_logfile); static HANDLE_FUNC (handle_logfile);
static HANDLE_FUNC(handle_loglevel); static HANDLE_FUNC (handle_loglevel);
static HANDLE_FUNC(handle_maxclients); static HANDLE_FUNC (handle_maxclients);
static HANDLE_FUNC(handle_maxrequestsperchild); static HANDLE_FUNC (handle_maxrequestsperchild);
static HANDLE_FUNC(handle_maxspareservers); static HANDLE_FUNC (handle_maxspareservers);
static HANDLE_FUNC(handle_minspareservers); static HANDLE_FUNC (handle_minspareservers);
static HANDLE_FUNC(handle_pidfile); static HANDLE_FUNC (handle_pidfile);
static HANDLE_FUNC(handle_port); static HANDLE_FUNC (handle_port);
#ifdef REVERSE_SUPPORT #ifdef REVERSE_SUPPORT
static HANDLE_FUNC(handle_reversebaseurl); static HANDLE_FUNC (handle_reversebaseurl);
static HANDLE_FUNC(handle_reversemagic); static HANDLE_FUNC (handle_reversemagic);
static HANDLE_FUNC(handle_reverseonly); static HANDLE_FUNC (handle_reverseonly);
static HANDLE_FUNC(handle_reversepath); static HANDLE_FUNC (handle_reversepath);
#endif #endif
static HANDLE_FUNC(handle_startservers); static HANDLE_FUNC (handle_startservers);
static HANDLE_FUNC(handle_statfile); static HANDLE_FUNC (handle_statfile);
static HANDLE_FUNC(handle_stathost); static HANDLE_FUNC (handle_stathost);
static HANDLE_FUNC(handle_syslog); static HANDLE_FUNC (handle_syslog);
static HANDLE_FUNC(handle_timeout); static HANDLE_FUNC (handle_timeout);
static HANDLE_FUNC(handle_user); static HANDLE_FUNC (handle_user);
static HANDLE_FUNC(handle_viaproxyname); static HANDLE_FUNC (handle_viaproxyname);
static HANDLE_FUNC(handle_xtinyproxy); static HANDLE_FUNC (handle_xtinyproxy);
#ifdef UPSTREAM_SUPPORT #ifdef UPSTREAM_SUPPORT
static HANDLE_FUNC(handle_upstream); static HANDLE_FUNC (handle_upstream);
static HANDLE_FUNC(handle_upstream_no); static HANDLE_FUNC (handle_upstream_no);
#endif #endif
/* /*
@ -156,82 +157,77 @@ static HANDLE_FUNC(handle_upstream_no);
* for internal use, a pointer to the compiled regex so it only needs * for internal use, a pointer to the compiled regex so it only needs
* to be compiled one. * to be compiled one.
*/ */
struct { struct
{
const char *re; const char *re;
CONFFILE_HANDLER handler; CONFFILE_HANDLER handler;
regex_t *cre; regex_t *cre;
} directives[] = { } directives[] =
{
/* comments */ /* comments */
{ BEGIN "#", handle_nop }, {
BEGIN "#", handle_nop},
/* blank lines */ /* blank lines */
{ "^[[:space:]]+$", handle_nop }, {
"^[[:space:]]+$", handle_nop},
/* string arguments */ /* string arguments */
STDCONF("logfile", STR, handle_logfile), STDCONF ("logfile", STR, handle_logfile),
STDCONF("pidfile", STR, handle_pidfile), STDCONF ("pidfile", STR, handle_pidfile),
STDCONF("anonymous", STR, handle_anonymous), STDCONF ("anonymous", STR, handle_anonymous),
STDCONF("viaproxyname", STR, handle_viaproxyname), STDCONF ("viaproxyname", STR, handle_viaproxyname),
STDCONF("defaulterrorfile", STR, handle_defaulterrorfile), STDCONF ("defaulterrorfile", STR, handle_defaulterrorfile),
STDCONF("statfile", STR, handle_statfile), STDCONF ("statfile", STR, handle_statfile),
STDCONF("stathost", STR, handle_stathost), STDCONF ("stathost", STR, handle_stathost),
STDCONF("xtinyproxy", STR, handle_xtinyproxy), STDCONF ("xtinyproxy", STR, handle_xtinyproxy),
/* boolean arguments */ /* boolean arguments */
STDCONF("syslog", BOOL, handle_syslog), STDCONF ("syslog", BOOL, handle_syslog),
STDCONF("bindsame", BOOL, handle_bindsame), STDCONF ("bindsame", BOOL, handle_bindsame),
/* integer arguments */ /* integer arguments */
STDCONF("port", INT, handle_port), STDCONF ("port", INT, handle_port),
STDCONF("maxclients", INT, handle_maxclients), STDCONF ("maxclients", INT, handle_maxclients),
STDCONF("maxspareservers", INT, handle_maxspareservers), STDCONF ("maxspareservers", INT, handle_maxspareservers),
STDCONF("minspareservers", INT, handle_minspareservers), STDCONF ("minspareservers", INT, handle_minspareservers),
STDCONF("startservers", INT, handle_startservers), STDCONF ("startservers", INT, handle_startservers),
STDCONF("maxrequestsperchild", INT, handle_maxrequestsperchild), STDCONF ("maxrequestsperchild", INT, handle_maxrequestsperchild),
STDCONF("timeout", INT, handle_timeout), STDCONF ("timeout", INT, handle_timeout),
STDCONF("connectport", INT, handle_connectport), STDCONF ("connectport", INT, handle_connectport),
/* alphanumeric arguments */ /* alphanumeric arguments */
STDCONF("user", ALNUM, handle_user), STDCONF ("user", ALNUM, handle_user),
STDCONF("group", ALNUM, handle_group), STDCONF ("group", ALNUM, handle_group),
/* ip arguments */ /* ip arguments */
STDCONF("listen", IP, handle_listen), STDCONF ("listen", IP, handle_listen),
STDCONF("allow", "(" IPMASK "|" ALNUM ")", handle_allow), STDCONF ("allow", "(" IPMASK "|" ALNUM ")", handle_allow),
STDCONF("deny", "(" IPMASK "|" ALNUM ")", handle_deny), STDCONF ("deny", "(" IPMASK "|" ALNUM ")", handle_deny),
STDCONF("bind", IP, handle_bind), STDCONF ("bind", IP, handle_bind),
/* error files */ /* error files */
STDCONF("errorfile", INT WS STR, handle_errorfile), STDCONF ("errorfile", INT WS STR, handle_errorfile),
#ifdef FILTER_ENABLE #ifdef FILTER_ENABLE
/* filtering */ /* filtering */
STDCONF("filter", STR, handle_filter), STDCONF ("filter", STR, handle_filter),
STDCONF("filterurls", BOOL, handle_filterurls), STDCONF ("filterurls", BOOL, handle_filterurls),
STDCONF("filterextended", BOOL, handle_filterextended), STDCONF ("filterextended", BOOL, handle_filterextended),
STDCONF("filterdefaultdeny", BOOL, handle_filterdefaultdeny), STDCONF ("filterdefaultdeny", BOOL, handle_filterdefaultdeny),
STDCONF("filtercasesensitive", BOOL, handle_filtercasesensitive), STDCONF ("filtercasesensitive", BOOL, handle_filtercasesensitive),
#endif #endif
#ifdef REVERSE_SUPPORT #ifdef REVERSE_SUPPORT
/* Reverse proxy arguments */ /* Reverse proxy arguments */
STDCONF("reversebaseurl", STR, handle_reversebaseurl), STDCONF ("reversebaseurl", STR, handle_reversebaseurl),
STDCONF("reverseonly", BOOL, handle_reverseonly), STDCONF ("reverseonly", BOOL, handle_reverseonly),
STDCONF("reversemagic", BOOL, handle_reversemagic), STDCONF ("reversemagic", BOOL, handle_reversemagic),
STDCONF("reversepath", STR WS "(" STR ")?", handle_reversepath), STDCONF ("reversepath", STR WS "(" STR ")?", handle_reversepath),
#endif #endif
#ifdef UPSTREAM_SUPPORT #ifdef UPSTREAM_SUPPORT
/* upstream is rather complicated */ /* 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 }, BEGIN "(no" WS "upstream)" WS STR END, handle_upstream_no},
{
BEGIN "(upstream)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR ")?" END,
handle_upstream},
#endif #endif
/* loglevel */ /* loglevel */
STDCONF("loglevel", "(critical|error|warning|notice|connect|info)", STDCONF ("loglevel", "(critical|error|warning|notice|connect|info)",
handle_loglevel) handle_loglevel)};
}; const unsigned int ndirectives = sizeof (directives) / sizeof (directives[0]);
const unsigned int ndirectives = sizeof(directives) / sizeof(directives[0]);
/* /*
* Compiles the regular expressions used by the configuration file. This * Compiles the regular expressions used by the configuration file. This
@ -240,21 +236,21 @@ const unsigned int ndirectives = sizeof(directives) / sizeof(directives[0]);
* Returns 0 on success; negative upon failure. * Returns 0 on success; negative upon failure.
*/ */
int int
config_compile(void) config_compile (void)
{ {
int i, r; int i, r;
for (i = 0; i != ndirectives; ++i) { for (i = 0; i != ndirectives; ++i)
assert(directives[i].handler); {
assert(!directives[i].cre); assert (directives[i].handler);
assert (!directives[i].cre);
directives[i].cre = safemalloc(sizeof(regex_t)); directives[i].cre = safemalloc (sizeof (regex_t));
if (!directives[i].cre) if (!directives[i].cre)
return -1; return -1;
r = regcomp(directives[i].cre, r = regcomp (directives[i].cre,
directives[i].re, directives[i].re, REG_EXTENDED | REG_ICASE | REG_NEWLINE);
REG_EXTENDED | REG_ICASE | REG_NEWLINE);
if (r) if (r)
return r; return r;
} }
@ -270,16 +266,17 @@ config_compile(void)
* a negative number is returned. * a negative number is returned.
*/ */
static int 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]; regmatch_t match[RE_MAX_MATCHES];
unsigned int i; unsigned int i;
assert(ndirectives > 0); assert (ndirectives > 0);
for (i = 0; i != ndirectives; ++i) { for (i = 0; i != ndirectives; ++i)
assert(directives[i].cre); {
if (!regexec(directives[i].cre, line, RE_MAX_MATCHES, match, 0)) assert (directives[i].cre);
if (!regexec (directives[i].cre, line, RE_MAX_MATCHES, match, 0))
return (*directives[i].handler) (conf, line, match); return (*directives[i].handler) (conf, line, match);
} }
@ -290,14 +287,16 @@ check_match(struct config_s *conf, const char *line)
* Parse the previously opened configuration stream. * Parse the previously opened configuration stream.
*/ */
int int
config_parse(struct config_s *conf, FILE * f) config_parse (struct config_s *conf, FILE * f)
{ {
char buffer[1024]; /* 1KB lines should be plenty */ char buffer[1024]; /* 1KB lines should be plenty */
unsigned long lineno = 1; unsigned long lineno = 1;
while (fgets(buffer, sizeof(buffer), f)) { while (fgets (buffer, sizeof (buffer), f))
if (check_match(conf, buffer)) { {
printf("Syntax error on line %ld\n", lineno); if (check_match (conf, buffer))
{
printf ("Syntax error on line %ld\n", lineno);
return 1; return 1;
} }
++lineno; ++lineno;
@ -313,77 +312,78 @@ config_parse(struct config_s *conf, FILE * f)
***********************************************************************/ ***********************************************************************/
static char * static char *
get_string_arg(const char *line, regmatch_t * match) get_string_arg (const char *line, regmatch_t * match)
{ {
char *p; char *p;
const unsigned int len = match->rm_eo - match->rm_so; const unsigned int len = match->rm_eo - match->rm_so;
assert(line); assert (line);
assert(len > 0); assert (len > 0);
p = safemalloc(len + 1); p = safemalloc (len + 1);
if (!p) if (!p)
return NULL; return NULL;
memcpy(p, line + match->rm_so, len); memcpy (p, line + match->rm_so, len);
p[len] = '\0'; p[len] = '\0';
return p; return p;
} }
static int 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) if (!arg)
return -1; return -1;
*var = safestrdup(arg); *var = safestrdup (arg);
safefree(arg); safefree (arg);
return *var ? 0 : -1; return *var ? 0 : -1;
} }
static int 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 (line);
assert(match && match->rm_so != -1); assert (match && match->rm_so != -1);
/* "y"es or o"n" map as true, otherwise it's false. */ /* "y"es or o"n" map as true, otherwise it's false. */
if (tolower(p[0]) == 'y' || tolower(p[1]) == 'n') if (tolower (p[0]) == 'y' || tolower (p[1]) == 'n')
return 1; return 1;
else else
return 0; return 0;
} }
static int 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 (var);
assert(line); assert (line);
assert(match && match->rm_so != -1); assert (match && match->rm_so != -1);
*var = get_bool_arg(line, match); *var = get_bool_arg (line, match);
return 0; return 0;
} }
static inline long int 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 (line);
assert(match && match->rm_so != -1); 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)
{
assert(var);
assert(line);
assert(match);
*var = get_int_arg(line, match); static int
set_int_arg (int long *var, const char *line, regmatch_t * match)
{
assert (var);
assert (line);
assert (match);
*var = get_int_arg (line, match);
return 0; return 0;
} }
@ -406,217 +406,216 @@ set_int_arg(int long *var, const char *line, regmatch_t * match)
***********************************************************************/ ***********************************************************************/
static 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 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 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) if (!arg)
return -1; return -1;
anonymous_insert(arg); anonymous_insert (arg);
safefree(arg); safefree (arg);
return 0; return 0;
} }
static 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) if (r)
return r; return r;
log_message(LOG_INFO, log_message (LOG_INFO,
"Setting \"Via\" header proxy to %s", conf->via_proxy_name); "Setting \"Via\" header proxy to %s", conf->via_proxy_name);
return 0; return 0;
} }
static 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 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 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) if (r)
return r; return r;
log_message(LOG_INFO, "Stathost set to \"%s\"", conf->stathost); log_message (LOG_INFO, "Stathost set to \"%s\"", conf->stathost);
return 0; return 0;
} }
static static
HANDLE_FUNC(handle_xtinyproxy) HANDLE_FUNC (handle_xtinyproxy)
{ {
#ifdef XTINYPROXY_ENABLE #ifdef XTINYPROXY_ENABLE
return set_string_arg(&conf->my_domain, line, &match[2]); return set_string_arg (&conf->my_domain, line, &match[2]);
#else #else
fprintf(stderr, fprintf (stderr,
"XTinyproxy NOT Enabled! Recompile with --enable-xtinyproxy\n"); "XTinyproxy NOT Enabled! Recompile with --enable-xtinyproxy\n");
return 1; return 1;
#endif #endif
} }
static static
HANDLE_FUNC(handle_syslog) HANDLE_FUNC (handle_syslog)
{ {
#ifdef HAVE_SYSLOG_H #ifdef HAVE_SYSLOG_H
return set_bool_arg(&conf->syslog, line, &match[2]); return set_bool_arg (&conf->syslog, line, &match[2]);
#else #else
fprintf(stderr, "Syslog support not compiled in executable.\n"); fprintf (stderr, "Syslog support not compiled in executable.\n");
return 1; return 1;
#endif #endif
} }
static 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) if (r)
return r; return r;
log_message(LOG_INFO, "Binding outgoing connection to incoming IP"); log_message (LOG_INFO, "Binding outgoing connection to incoming IP");
return 0; return 0;
} }
static 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 static
HANDLE_FUNC(handle_maxclients) HANDLE_FUNC (handle_maxclients)
{ {
child_configure(CHILD_MAXCLIENTS, get_int_arg(line, &match[2])); child_configure (CHILD_MAXCLIENTS, get_int_arg (line, &match[2]));
return 0; return 0;
} }
static static
HANDLE_FUNC(handle_maxspareservers) HANDLE_FUNC (handle_maxspareservers)
{ {
child_configure(CHILD_MAXSPARESERVERS, get_int_arg(line, &match[2])); child_configure (CHILD_MAXSPARESERVERS, get_int_arg (line, &match[2]));
return 0; return 0;
} }
static static
HANDLE_FUNC(handle_minspareservers) HANDLE_FUNC (handle_minspareservers)
{ {
child_configure(CHILD_MINSPARESERVERS, get_int_arg(line, &match[2])); child_configure (CHILD_MINSPARESERVERS, get_int_arg (line, &match[2]));
return 0; return 0;
} }
static static
HANDLE_FUNC(handle_startservers) HANDLE_FUNC (handle_startservers)
{ {
child_configure(CHILD_STARTSERVERS, get_int_arg(line, &match[2])); child_configure (CHILD_STARTSERVERS, get_int_arg (line, &match[2]));
return 0; return 0;
} }
static static
HANDLE_FUNC(handle_maxrequestsperchild) HANDLE_FUNC (handle_maxrequestsperchild)
{ {
child_configure(CHILD_MAXREQUESTSPERCHILD, child_configure (CHILD_MAXREQUESTSPERCHILD, get_int_arg (line, &match[2]));
get_int_arg(line, &match[2]));
return 0; return 0;
} }
static 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 static
HANDLE_FUNC(handle_connectport) HANDLE_FUNC (handle_connectport)
{ {
add_connect_port_allowed(get_int_arg(line, &match[2])); add_connect_port_allowed (get_int_arg (line, &match[2]));
return 0; return 0;
} }
static 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 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 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); insert_acl (arg, ACL_ALLOW);
safefree(arg); safefree (arg);
return 0; return 0;
} }
static 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); insert_acl (arg, ACL_DENY);
safefree(arg); safefree (arg);
return 0; return 0;
} }
static static
HANDLE_FUNC(handle_bind) HANDLE_FUNC (handle_bind)
{ {
#ifndef TRANSPARENT_PROXY #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) if (r)
return r; return r;
log_message(LOG_INFO, log_message (LOG_INFO,
"Outgoing connections bound to IP %s", conf->bind_address); "Outgoing connections bound to IP %s", conf->bind_address);
return 0; return 0;
#else #else
fprintf(stderr, fprintf (stderr,
"\"Bind\" cannot be used with transparent support enabled.\n"); "\"Bind\" cannot be used with transparent support enabled.\n");
return 1; return 1;
#endif #endif
} }
static 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) if (r)
return r; return r;
log_message(LOG_INFO, "Listing on IP %s", conf->ipAddr); log_message (LOG_INFO, "Listing on IP %s", conf->ipAddr);
return 0; return 0;
} }
static static
HANDLE_FUNC(handle_errorfile) HANDLE_FUNC (handle_errorfile)
{ {
/* /*
* Because an integer is defined as ((0x)?[[:digit:]]+) _two_ * Because an integer is defined as ((0x)?[[:digit:]]+) _two_
@ -625,18 +624,19 @@ HANDLE_FUNC(handle_errorfile)
* present. This is why the "string" is located at * present. This is why the "string" is located at
* match[4] (rather than the more intuitive match[3]. * match[4] (rather than the more intuitive match[3].
*/ */
long int err = get_int_arg(line, &match[2]); long int err = get_int_arg (line, &match[2]);
char *page = get_string_arg(line, &match[4]); char *page = get_string_arg (line, &match[4]);
add_new_errorpage(page, err); add_new_errorpage (page, err);
safefree(page); safefree (page);
return 0; return 0;
} }
/* /*
* Log level's strings. * Log level's strings.
*/ */
struct log_levels_s { struct log_levels_s
{
const char *string; const char *string;
int level; int level;
}; };
@ -650,105 +650,111 @@ static struct log_levels_s log_levels[] = {
}; };
static static
HANDLE_FUNC(handle_loglevel) HANDLE_FUNC (handle_loglevel)
{ {
static const unsigned int nlevels = static const unsigned int nlevels =
sizeof(log_levels) / sizeof(log_levels[0]); sizeof (log_levels) / sizeof (log_levels[0]);
unsigned int i; 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) { for (i = 0; i != nlevels; ++i)
if (!strcasecmp(arg, log_levels[i].string)) { {
set_log_level(log_levels[i].level); if (!strcasecmp (arg, log_levels[i].string))
safefree(arg); {
set_log_level (log_levels[i].level);
safefree (arg);
return 0; return 0;
} }
} }
safefree(arg); safefree (arg);
return -1; return -1;
} }
#ifdef FILTER_ENABLE #ifdef FILTER_ENABLE
static 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 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 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 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])) if (get_bool_arg (line, &match[2]))
filter_set_default_policy(FILTER_DEFAULT_DENY); filter_set_default_policy (FILTER_DEFAULT_DENY);
return 0; return 0;
} }
static 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 #endif
#ifdef REVERSE_SUPPORT #ifdef REVERSE_SUPPORT
static 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 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 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 static
HANDLE_FUNC(handle_reversepath) HANDLE_FUNC (handle_reversepath)
{ {
/* /*
* The second string argument is optional. * The second string argument is optional.
*/ */
char *arg1, *arg2; char *arg1, *arg2;
arg1 = get_string_arg(line, &match[2]); arg1 = get_string_arg (line, &match[2]);
if (!arg1) if (!arg1)
return -1; return -1;
if (match[3].rm_so != -1) { if (match[3].rm_so != -1)
arg2 = get_string_arg(line, &match[3]); {
if (!arg2) { arg2 = get_string_arg (line, &match[3]);
safefree(arg1); if (!arg2)
{
safefree (arg1);
return -1; return -1;
} }
reversepath_add(arg1, arg2); reversepath_add (arg1, arg2);
safefree(arg1); safefree (arg1);
safefree(arg2); safefree (arg2);
} else { }
reversepath_add(NULL, arg1); else
safefree(arg1); {
reversepath_add (NULL, arg1);
safefree (arg1);
} }
return 0; return 0;
} }
@ -756,41 +762,47 @@ HANDLE_FUNC(handle_reversepath)
#ifdef UPSTREAM_SUPPORT #ifdef UPSTREAM_SUPPORT
static static
HANDLE_FUNC(handle_upstream) HANDLE_FUNC (handle_upstream)
{ {
char *ip; char *ip;
int port; int port;
char *domain; char *domain;
ip = get_string_arg(line, &match[2]); ip = get_string_arg (line, &match[2]);
if (!ip) return -1; if (!ip)
port = get_int_arg(line, &match[7]); return -1;
port = get_int_arg (line, &match[7]);
if (match[9].rm_so != -1) { if (match[9].rm_so != -1)
domain = get_string_arg(line, &match[9]); {
if (domain) { domain = get_string_arg (line, &match[9]);
upstream_add(ip, port, domain); if (domain)
safefree(domain); {
upstream_add (ip, port, domain);
safefree (domain);
} }
} else { }
upstream_add(ip, port, NULL); else
{
upstream_add (ip, port, NULL);
} }
safefree(ip); safefree (ip);
return 0; return 0;
} }
static static
HANDLE_FUNC(handle_upstream_no) HANDLE_FUNC (handle_upstream_no)
{ {
char *domain; char *domain;
domain = get_string_arg(line, &match[2]); domain = get_string_arg (line, &match[2]);
if (!domain) return -1; if (!domain)
return -1;
upstream_add(NULL, 0, domain); upstream_add (NULL, 0, domain);
safefree(domain); safefree (domain);
return 0; return 0;
} }

View File

@ -21,7 +21,7 @@
#ifndef TINYPROXY_CONFFILE_H #ifndef TINYPROXY_CONFFILE_H
#define TINYPROXY_CONFFILE_H #define TINYPROXY_CONFFILE_H
extern int config_compile(void); extern int config_compile (void);
extern int config_parse(struct config_s *conf, FILE * f); extern int config_parse (struct config_s *conf, FILE * f);
#endif #endif

View File

@ -31,19 +31,19 @@
#include "stats.h" #include "stats.h"
struct conn_s * struct conn_s *
initialize_conn(int client_fd, const char *ipaddr, const char *string_addr, initialize_conn (int client_fd, const char *ipaddr, const char *string_addr,
const char *sock_ipaddr) const char *sock_ipaddr)
{ {
struct conn_s *connptr; struct conn_s *connptr;
struct buffer_s *cbuffer, *sbuffer; struct buffer_s *cbuffer, *sbuffer;
assert(client_fd >= 0); assert (client_fd >= 0);
/* /*
* Allocate the memory for all the internal components * Allocate the memory for all the internal components
*/ */
cbuffer = new_buffer(); cbuffer = new_buffer ();
sbuffer = new_buffer(); sbuffer = new_buffer ();
if (!cbuffer || !sbuffer) if (!cbuffer || !sbuffer)
goto error_exit; goto error_exit;
@ -51,7 +51,7 @@ initialize_conn(int client_fd, const char *ipaddr, const char *string_addr,
/* /*
* Allocate the space for the conn_s structure itself. * Allocate the space for the conn_s structure itself.
*/ */
connptr = safemalloc(sizeof(struct conn_s)); connptr = safemalloc (sizeof (struct conn_s));
if (!connptr) if (!connptr)
goto error_exit; goto error_exit;
@ -76,13 +76,13 @@ initialize_conn(int client_fd, const char *ipaddr, const char *string_addr,
/* There is _no_ content length initially */ /* There is _no_ content length initially */
connptr->content_length.server = connptr->content_length.client = -1; connptr->content_length.server = connptr->content_length.client = -1;
connptr->server_ip_addr = sock_ipaddr ? safestrdup(sock_ipaddr) : 0; connptr->server_ip_addr = sock_ipaddr ? safestrdup (sock_ipaddr) : 0;
connptr->client_ip_addr = safestrdup(ipaddr); connptr->client_ip_addr = safestrdup (ipaddr);
connptr->client_string_addr = safestrdup(string_addr); 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 #ifdef REVERSE_SUPPORT
connptr->reversepath = NULL; connptr->reversepath = NULL;
@ -90,59 +90,59 @@ initialize_conn(int client_fd, const char *ipaddr, const char *string_addr,
return connptr; return connptr;
error_exit: error_exit:
/* /*
* If we got here, there was a problem allocating memory * If we got here, there was a problem allocating memory
*/ */
if (cbuffer) if (cbuffer)
delete_buffer(cbuffer); delete_buffer (cbuffer);
if (sbuffer) if (sbuffer)
delete_buffer(sbuffer); delete_buffer (sbuffer);
return NULL; return NULL;
} }
void void
destroy_conn(struct conn_s *connptr) destroy_conn (struct conn_s *connptr)
{ {
assert(connptr != NULL); assert (connptr != NULL);
if (connptr->client_fd != -1) if (connptr->client_fd != -1)
if (close(connptr->client_fd) < 0) if (close (connptr->client_fd) < 0)
log_message(LOG_INFO, "Client (%d) close message: %s", log_message (LOG_INFO, "Client (%d) close message: %s",
connptr->client_fd, strerror(errno)); connptr->client_fd, strerror (errno));
if (connptr->server_fd != -1) if (connptr->server_fd != -1)
if (close(connptr->server_fd) < 0) if (close (connptr->server_fd) < 0)
log_message(LOG_INFO, "Server (%d) close message: %s", log_message (LOG_INFO, "Server (%d) close message: %s",
connptr->server_fd, strerror(errno)); connptr->server_fd, strerror (errno));
if (connptr->cbuffer) if (connptr->cbuffer)
delete_buffer(connptr->cbuffer); delete_buffer (connptr->cbuffer);
if (connptr->sbuffer) if (connptr->sbuffer)
delete_buffer(connptr->sbuffer); delete_buffer (connptr->sbuffer);
if (connptr->request_line) if (connptr->request_line)
safefree(connptr->request_line); safefree (connptr->request_line);
if (connptr->error_variables) if (connptr->error_variables)
hashmap_delete(connptr->error_variables); hashmap_delete (connptr->error_variables);
if (connptr->error_string) if (connptr->error_string)
safefree(connptr->error_string); safefree (connptr->error_string);
if (connptr->server_ip_addr) if (connptr->server_ip_addr)
safefree(connptr->server_ip_addr); safefree (connptr->server_ip_addr);
if (connptr->client_ip_addr) if (connptr->client_ip_addr)
safefree(connptr->client_ip_addr); safefree (connptr->client_ip_addr);
if (connptr->client_string_addr) if (connptr->client_string_addr)
safefree(connptr->client_string_addr); safefree (connptr->client_string_addr);
#ifdef REVERSE_SUPPORT #ifdef REVERSE_SUPPORT
if (connptr->reversepath) if (connptr->reversepath)
safefree(connptr->reversepath); safefree (connptr->reversepath);
#endif #endif
safefree(connptr); safefree (connptr);
update_stats(STAT_CLOSE); update_stats (STAT_CLOSE);
} }

View File

@ -27,7 +27,8 @@
/* /*
* Connection Definition * Connection Definition
*/ */
struct conn_s { struct conn_s
{
int client_fd; int client_fd;
int server_fd; int server_fd;
@ -51,7 +52,8 @@ struct conn_s {
char *error_string; char *error_string;
/* A Content-Length value from the remote server */ /* A Content-Length value from the remote server */
struct { struct
{
long int server; long int server;
long int client; long int client;
} content_length; } content_length;
@ -70,7 +72,8 @@ struct conn_s {
/* /*
* Store the incoming request's HTTP protocol. * Store the incoming request's HTTP protocol.
*/ */
struct { struct
{
unsigned int major; unsigned int major;
unsigned int minor; unsigned int minor;
} protocol; } protocol;
@ -91,9 +94,9 @@ struct conn_s {
/* /*
* Functions for the creation and destruction of a connection structure. * Functions for the creation and destruction of a connection structure.
*/ */
extern struct conn_s *initialize_conn(int client_fd, const char *ipaddr, extern struct conn_s *initialize_conn (int client_fd, const char *ipaddr,
const char *string_addr, const char *string_addr,
const char *sock_ipaddr); const char *sock_ipaddr);
extern void destroy_conn(struct conn_s *connptr); extern void destroy_conn (struct conn_s *connptr);
#endif #endif

View File

@ -30,28 +30,28 @@
* program a daemon process. * program a daemon process.
*/ */
void void
makedaemon(void) makedaemon (void)
{ {
if (fork() != 0) if (fork () != 0)
exit(0); exit (0);
setsid(); setsid ();
set_signal_handler(SIGHUP, SIG_IGN); set_signal_handler (SIGHUP, SIG_IGN);
if (fork() != 0) if (fork () != 0)
exit(0); exit (0);
chdir("/"); chdir ("/");
umask(0177); umask (0177);
#if NDEBUG #if NDEBUG
/* /*
* When not in debugging mode, close the standard file * When not in debugging mode, close the standard file
* descriptors. * descriptors.
*/ */
close(0); close (0);
close(1); close (1);
close(2); close (2);
#endif #endif
} }
@ -60,24 +60,27 @@ makedaemon(void)
* to handle signals sent to the process. * to handle signals sent to the process.
*/ */
signal_func * 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; act.sa_handler = func;
sigemptyset(&act.sa_mask); sigemptyset (&act.sa_mask);
act.sa_flags = 0; act.sa_flags = 0;
if (signo == SIGALRM) { if (signo == SIGALRM)
{
#ifdef SA_INTERRUPT #ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */ act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */
#endif #endif
} else { }
else
{
#ifdef SA_RESTART #ifdef SA_RESTART
act.sa_flags |= SA_RESTART; /* SVR4, 4.4BSD */ act.sa_flags |= SA_RESTART; /* SVR4, 4.4BSD */
#endif #endif
} }
if (sigaction(signo, &act, &oact) < 0) if (sigaction (signo, &act, &oact) < 0)
return SIG_ERR; return SIG_ERR;
return oact.sa_handler; return oact.sa_handler;

View File

@ -26,11 +26,11 @@ typedef void signal_func (int);
/* /*
* Pass a singal integer and a function to handle the signal. * 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 * Make a program a daemon process
*/ */
extern void makedaemon(void); extern void makedaemon (void);
#endif #endif

View File

@ -33,7 +33,8 @@
static int err; static int err;
struct filter_list { struct filter_list
{
struct filter_list *next; struct filter_list *next;
char *pat; char *pat;
regex_t *cpat; regex_t *cpat;
@ -47,7 +48,7 @@ static filter_policy_t default_policy = FILTER_DEFAULT_ALLOW;
* Initializes a linked list of strings containing hosts/urls to be filtered * Initializes a linked list of strings containing hosts/urls to be filtered
*/ */
void void
filter_init(void) filter_init (void)
{ {
FILE *fd; FILE *fd;
struct filter_list *p; struct filter_list *p;
@ -55,9 +56,11 @@ filter_init(void)
char *s; char *s;
int cflags; int cflags;
if (!fl && !already_init) { if (!fl && !already_init)
fd = fopen(config.filter, "r"); {
if (fd) { fd = fopen (config.filter, "r");
if (fd)
{
p = NULL; p = NULL;
cflags = REG_NEWLINE | REG_NOSUB; cflags = REG_NEWLINE | REG_NOSUB;
@ -66,23 +69,25 @@ filter_init(void)
if (!config.filter_casesensitive) if (!config.filter_casesensitive)
cflags |= REG_ICASE; cflags |= REG_ICASE;
while (fgets(buf, FILTER_BUFFER_LEN, fd)) { while (fgets (buf, FILTER_BUFFER_LEN, fd))
{
/* /*
* Remove any trailing white space and * Remove any trailing white space and
* comments. * comments.
*/ */
s = buf; s = buf;
while (*s) { while (*s)
if (isspace((unsigned char)*s)) {
if (isspace ((unsigned char) *s))
break; break;
if (*s == '#') { if (*s == '#')
{
/* /*
* If the '#' char is preceeded by * If the '#' char is preceeded by
* an escape, it's not a comment * an escape, it's not a comment
* string. * string.
*/ */
if (s == buf if (s == buf || *(s - 1) != '\\')
|| *(s - 1) != '\\')
break; break;
} }
++s; ++s;
@ -91,7 +96,7 @@ filter_init(void)
/* skip leading whitespace */ /* skip leading whitespace */
s = buf; s = buf;
while (*s && isspace((unsigned char)*s)) while (*s && isspace ((unsigned char) *s))
s++; s++;
/* skip blank lines and comments */ /* skip blank lines and comments */
@ -99,32 +104,28 @@ filter_init(void)
continue; continue;
if (!p) /* head of list */ if (!p) /* head of list */
fl = p = fl = p = safecalloc (1, sizeof (struct filter_list));
safecalloc(1, else
sizeof(struct { /* next entry */
filter_list)); p->next = safecalloc (1, sizeof (struct filter_list));
else { /* next entry */
p->next =
safecalloc(1,
sizeof(struct
filter_list));
p = p->next; p = p->next;
} }
p->pat = safestrdup(s); p->pat = safestrdup (s);
p->cpat = safemalloc(sizeof(regex_t)); p->cpat = safemalloc (sizeof (regex_t));
if ((err = if ((err = regcomp (p->cpat, p->pat, cflags)) != 0)
regcomp(p->cpat, p->pat, cflags)) != 0) { {
fprintf(stderr, "Bad regex in %s: %s\n", fprintf (stderr, "Bad regex in %s: %s\n",
config.filter, p->pat); config.filter, p->pat);
exit(EX_DATAERR); exit (EX_DATAERR);
} }
} }
if (ferror(fd)) { if (ferror (fd))
perror("fgets"); {
exit(EX_DATAERR); perror ("fgets");
exit (EX_DATAERR);
} }
fclose(fd); fclose (fd);
already_init = 1; already_init = 1;
} }
@ -133,17 +134,19 @@ filter_init(void)
/* unlink the list */ /* unlink the list */
void void
filter_destroy(void) filter_destroy (void)
{ {
struct filter_list *p, *q; struct filter_list *p, *q;
if (already_init) { if (already_init)
for (p = q = fl; p; p = q) { {
regfree(p->cpat); for (p = q = fl; p; p = q)
safefree(p->cpat); {
safefree(p->pat); regfree (p->cpat);
safefree (p->cpat);
safefree (p->pat);
q = p->next; q = p->next;
safefree(p); safefree (p);
} }
fl = NULL; fl = NULL;
already_init = 0; already_init = 0;
@ -152,7 +155,7 @@ filter_destroy(void)
/* Return 0 to allow, non-zero to block */ /* Return 0 to allow, non-zero to block */
int int
filter_domain(const char *host) filter_domain (const char *host)
{ {
struct filter_list *p; struct filter_list *p;
int result; int result;
@ -160,11 +163,12 @@ filter_domain(const char *host)
if (!fl || !already_init) if (!fl || !already_init)
goto COMMON_EXIT; goto COMMON_EXIT;
for (p = fl; p; p = p->next) { for (p = fl; p; p = p->next)
result = {
regexec(p->cpat, host, (size_t) 0, (regmatch_t *) 0, 0); result = regexec (p->cpat, host, (size_t) 0, (regmatch_t *) 0, 0);
if (result == 0) { if (result == 0)
{
if (default_policy == FILTER_DEFAULT_ALLOW) if (default_policy == FILTER_DEFAULT_ALLOW)
return 1; return 1;
else else
@ -172,7 +176,7 @@ filter_domain(const char *host)
} }
} }
COMMON_EXIT: COMMON_EXIT:
if (default_policy == FILTER_DEFAULT_ALLOW) if (default_policy == FILTER_DEFAULT_ALLOW)
return 0; return 0;
else else
@ -181,7 +185,7 @@ filter_domain(const char *host)
/* returns 0 to allow, non-zero to block */ /* returns 0 to allow, non-zero to block */
int int
filter_url(const char *url) filter_url (const char *url)
{ {
struct filter_list *p; struct filter_list *p;
int result; int result;
@ -189,10 +193,12 @@ filter_url(const char *url)
if (!fl || !already_init) if (!fl || !already_init)
goto COMMON_EXIT; goto COMMON_EXIT;
for (p = fl; p; p = p->next) { for (p = fl; p; p = p->next)
result = regexec(p->cpat, url, (size_t) 0, (regmatch_t *) 0, 0); {
result = regexec (p->cpat, url, (size_t) 0, (regmatch_t *) 0, 0);
if (result == 0) { if (result == 0)
{
if (default_policy == FILTER_DEFAULT_ALLOW) if (default_policy == FILTER_DEFAULT_ALLOW)
return 1; return 1;
else else
@ -200,7 +206,7 @@ filter_url(const char *url)
} }
} }
COMMON_EXIT: COMMON_EXIT:
if (default_policy == FILTER_DEFAULT_ALLOW) if (default_policy == FILTER_DEFAULT_ALLOW)
return 0; return 0;
else else
@ -211,7 +217,7 @@ filter_url(const char *url)
* Set the default filtering policy * Set the default filtering policy
*/ */
void void
filter_set_default_policy(filter_policy_t policy) filter_set_default_policy (filter_policy_t policy)
{ {
default_policy = policy; default_policy = policy;
} }

View File

@ -21,16 +21,17 @@
#ifndef _TINYPROXY_FILTER_H_ #ifndef _TINYPROXY_FILTER_H_
#define _TINYPROXY_FILTER_H_ #define _TINYPROXY_FILTER_H_
typedef enum { typedef enum
{
FILTER_DEFAULT_ALLOW, FILTER_DEFAULT_ALLOW,
FILTER_DEFAULT_DENY, FILTER_DEFAULT_DENY,
} filter_policy_t; } filter_policy_t;
extern void filter_init(void); extern void filter_init (void);
extern void filter_destroy(void); extern void filter_destroy (void);
extern int filter_domain(const char *host); extern int filter_domain (const char *host);
extern int filter_url(const char *url); 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 #endif

View File

@ -37,7 +37,8 @@
* internal use. It stores the number of buckets the hashmap was created * internal use. It stores the number of buckets the hashmap was created
* with. * with.
*/ */
struct hashentry_s { struct hashentry_s
{
char *key; char *key;
void *data; void *data;
size_t len; size_t len;
@ -45,11 +46,13 @@ struct hashentry_s {
struct hashentry_s *prev, *next; struct hashentry_s *prev, *next;
}; };
struct hashbucket_s { struct hashbucket_s
{
struct hashentry_s *head, *tail; struct hashentry_s *head, *tail;
}; };
struct hashmap_s { struct hashmap_s
{
unsigned int size; unsigned int size;
hashmap_iter end_iterator; hashmap_iter end_iterator;
@ -66,7 +69,7 @@ struct hashmap_s {
* If any of the arguments are invalid a negative number is returned. * If any of the arguments are invalid a negative number is returned.
*/ */
static int static int
hashfunc(const char *key, unsigned int size) hashfunc (const char *key, unsigned int size)
{ {
uint32_t hash; uint32_t hash;
@ -75,12 +78,13 @@ hashfunc(const char *key, unsigned int size)
if (size == 0) if (size == 0)
return -ERANGE; return -ERANGE;
for (hash = tolower(*key++); *key != '\0'; key++) { for (hash = tolower (*key++); *key != '\0'; key++)
uint32_t bit = (hash & 1) ? (1 << (sizeof(uint32_t) - 1)) : 0; {
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 */ /* Keep the hash within the table limits */
@ -95,21 +99,22 @@ hashfunc(const char *key, unsigned int size)
* NULLs are also returned if memory could not be allocated for hashmap. * NULLs are also returned if memory could not be allocated for hashmap.
*/ */
hashmap_t hashmap_t
hashmap_create(unsigned int nbuckets) hashmap_create (unsigned int nbuckets)
{ {
struct hashmap_s *ptr; struct hashmap_s *ptr;
if (nbuckets == 0) if (nbuckets == 0)
return NULL; return NULL;
ptr = safecalloc(1, sizeof(struct hashmap_s)); ptr = safecalloc (1, sizeof (struct hashmap_s));
if (!ptr) if (!ptr)
return NULL; return NULL;
ptr->size = nbuckets; ptr->size = nbuckets;
ptr->buckets = safecalloc(nbuckets, sizeof(struct hashbucket_s)); ptr->buckets = safecalloc (nbuckets, sizeof (struct hashbucket_s));
if (!ptr->buckets) { if (!ptr->buckets)
safefree(ptr); {
safefree (ptr);
return NULL; return NULL;
} }
@ -127,7 +132,7 @@ hashmap_create(unsigned int nbuckets)
* negative number is returned if "entry" was NULL * negative number is returned if "entry" was NULL
*/ */
static inline int static inline int
delete_hashbucket(struct hashbucket_s *bucket) delete_hashbucket (struct hashbucket_s *bucket)
{ {
struct hashentry_s *nextptr; struct hashentry_s *nextptr;
struct hashentry_s *ptr; struct hashentry_s *ptr;
@ -136,12 +141,13 @@ delete_hashbucket(struct hashbucket_s *bucket)
return -EINVAL; return -EINVAL;
ptr = bucket->head; ptr = bucket->head;
while (ptr) { while (ptr)
{
nextptr = ptr->next; nextptr = ptr->next;
safefree(ptr->key); safefree (ptr->key);
safefree(ptr->data); safefree (ptr->data);
safefree(ptr); safefree (ptr);
ptr = nextptr; ptr = nextptr;
} }
@ -156,21 +162,23 @@ delete_hashbucket(struct hashbucket_s *bucket)
* negative if a NULL "map" was supplied * negative if a NULL "map" was supplied
*/ */
int int
hashmap_delete(hashmap_t map) hashmap_delete (hashmap_t map)
{ {
unsigned int i; unsigned int i;
if (map == NULL) if (map == NULL)
return -EINVAL; return -EINVAL;
for (i = 0; i != map->size; i++) { for (i = 0; i != map->size; i++)
if (map->buckets[i].head != NULL) { {
delete_hashbucket(&map->buckets[i]); if (map->buckets[i].head != NULL)
{
delete_hashbucket (&map->buckets[i]);
} }
} }
safefree(map->buckets); safefree (map->buckets);
safefree(map); safefree (map);
return 0; return 0;
} }
@ -186,24 +194,24 @@ hashmap_delete(hashmap_t map)
* negative number if there are errors * negative number if there are errors
*/ */
int 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; struct hashentry_s *ptr;
int hash; int hash;
char *key_copy; char *key_copy;
void *data_copy; void *data_copy;
assert(map != NULL); assert (map != NULL);
assert(key != NULL); assert (key != NULL);
assert(data != NULL); assert (data != NULL);
assert(len > 0); assert (len > 0);
if (map == NULL || key == NULL) if (map == NULL || key == NULL)
return -EINVAL; return -EINVAL;
if (!data || len < 1) if (!data || len < 1)
return -ERANGE; return -ERANGE;
hash = hashfunc(key, map->size); hash = hashfunc (key, map->size);
if (hash < 0) if (hash < 0)
return hash; return hash;
@ -211,21 +219,23 @@ hashmap_insert(hashmap_t map, const char *key, const void *data, size_t len)
* First make copies of the key and data in case there is a memory * First make copies of the key and data in case there is a memory
* problem later. * problem later.
*/ */
key_copy = safestrdup(key); key_copy = safestrdup (key);
if (!key_copy) if (!key_copy)
return -ENOMEM; return -ENOMEM;
data_copy = safemalloc(len); data_copy = safemalloc (len);
if (!data_copy) { if (!data_copy)
safefree(key_copy); {
safefree (key_copy);
return -ENOMEM; return -ENOMEM;
} }
memcpy(data_copy, data, len); memcpy (data_copy, data, len);
ptr = safemalloc(sizeof(struct hashentry_s)); ptr = safemalloc (sizeof (struct hashentry_s));
if (!ptr) { if (!ptr)
safefree(key_copy); {
safefree(data_copy); safefree (key_copy);
safefree (data_copy);
return -ENOMEM; return -ENOMEM;
} }
@ -255,9 +265,9 @@ hashmap_insert(hashmap_t map, const char *key, const void *data, size_t len)
* Returns: an negative value upon error. * Returns: an negative value upon error.
*/ */
hashmap_iter hashmap_iter
hashmap_first(hashmap_t map) hashmap_first (hashmap_t map)
{ {
assert(map != NULL); assert (map != NULL);
if (!map) if (!map)
return -EINVAL; return -EINVAL;
@ -275,10 +285,10 @@ hashmap_first(hashmap_t map)
* 0 otherwise * 0 otherwise
*/ */
int int
hashmap_is_end(hashmap_t map, hashmap_iter iter) hashmap_is_end (hashmap_t map, hashmap_iter iter)
{ {
assert(map != NULL); assert (map != NULL);
assert(iter >= 0); assert (iter >= 0);
if (!map || iter < 0) if (!map || iter < 0)
return -EINVAL; return -EINVAL;
@ -298,14 +308,14 @@ hashmap_is_end(hashmap_t map, hashmap_iter iter)
* an "end-iterator" if the key wasn't found * an "end-iterator" if the key wasn't found
*/ */
hashmap_iter hashmap_iter
hashmap_find(hashmap_t map, const char *key) hashmap_find (hashmap_t map, const char *key)
{ {
unsigned int i; unsigned int i;
hashmap_iter iter = 0; hashmap_iter iter = 0;
struct hashentry_s *ptr; struct hashentry_s *ptr;
assert(map != NULL); assert (map != NULL);
assert(key != NULL); assert (key != NULL);
if (!map || !key) if (!map || !key)
return -EINVAL; return -EINVAL;
@ -314,11 +324,14 @@ hashmap_find(hashmap_t map, const char *key)
* Loop through all the keys and look for the first occurrence * Loop through all the keys and look for the first occurrence
* of a particular key. * of a particular key.
*/ */
for (i = 0; i != map->size; i++) { for (i = 0; i != map->size; i++)
{
ptr = map->buckets[i].head; ptr = map->buckets[i].head;
while (ptr) { while (ptr)
if (strcasecmp(ptr->key, key) == 0) { {
if (strcasecmp (ptr->key, key) == 0)
{
/* Found it, so return the current count */ /* Found it, so return the current count */
return iter; return iter;
} }
@ -338,25 +351,29 @@ hashmap_find(hashmap_t map, const char *key)
* negative upon error * negative upon error
*/ */
ssize_t 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; unsigned int i;
struct hashentry_s *ptr; struct hashentry_s *ptr;
hashmap_iter count = 0; hashmap_iter count = 0;
assert(map != NULL); assert (map != NULL);
assert(iter >= 0); assert (iter >= 0);
assert(iter != map->end_iterator); assert (iter != map->end_iterator);
assert(key != NULL); assert (key != NULL);
assert(data != NULL); assert (data != NULL);
if (!map || iter < 0 || !key || !data) if (!map || iter < 0 || !key || !data)
return -EINVAL; return -EINVAL;
for (i = 0; i != map->size; i++) { for (i = 0; i != map->size; i++)
{
ptr = map->buckets[i].head; ptr = map->buckets[i].head;
while (ptr) { while (ptr)
if (count == iter) { {
if (count == iter)
{
/* This is the data so return it */ /* This is the data so return it */
*key = ptr->key; *key = ptr->key;
*data = ptr->data; *data = ptr->data;
@ -379,7 +396,7 @@ hashmap_return_entry(hashmap_t map, hashmap_iter iter, char **key, void **data)
* count found * count found
*/ */
ssize_t ssize_t
hashmap_search(hashmap_t map, const char *key) hashmap_search (hashmap_t map, const char *key)
{ {
int hash; int hash;
struct hashentry_s *ptr; struct hashentry_s *ptr;
@ -388,15 +405,16 @@ hashmap_search(hashmap_t map, const char *key)
if (map == NULL || key == NULL) if (map == NULL || key == NULL)
return -EINVAL; return -EINVAL;
hash = hashfunc(key, map->size); hash = hashfunc (key, map->size);
if (hash < 0) if (hash < 0)
return hash; 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 */ /* All right, there is an entry here, now see if it's the one we want */
while (ptr) { while (ptr)
if (strcasecmp(ptr->key, key) == 0) {
if (strcasecmp (ptr->key, key) == 0)
++count; ++count;
/* This entry didn't contain the key; move to the next one */ /* This entry didn't contain the key; move to the next one */
@ -415,7 +433,7 @@ hashmap_search(hashmap_t map, const char *key)
* length of data for the entry * length of data for the entry
*/ */
ssize_t 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; int hash;
struct hashentry_s *ptr; struct hashentry_s *ptr;
@ -423,14 +441,16 @@ hashmap_entry_by_key(hashmap_t map, const char *key, void **data)
if (!map || !key || !data) if (!map || !key || !data)
return -EINVAL; return -EINVAL;
hash = hashfunc(key, map->size); hash = hashfunc (key, map->size);
if (hash < 0) if (hash < 0)
return hash; return hash;
ptr = map->buckets[hash].head; ptr = map->buckets[hash].head;
while (ptr) { while (ptr)
if (strcasecmp(ptr->key, key) == 0) { {
if (strcasecmp (ptr->key, key) == 0)
{
*data = ptr->data; *data = ptr->data;
return ptr->len; return ptr->len;
} }
@ -450,7 +470,7 @@ hashmap_entry_by_key(hashmap_t map, const char *key, void **data)
* positive count of entries deleted * positive count of entries deleted
*/ */
ssize_t ssize_t
hashmap_remove(hashmap_t map, const char *key) hashmap_remove (hashmap_t map, const char *key)
{ {
int hash; int hash;
struct hashentry_s *ptr, *next; struct hashentry_s *ptr, *next;
@ -459,13 +479,15 @@ hashmap_remove(hashmap_t map, const char *key)
if (map == NULL || key == NULL) if (map == NULL || key == NULL)
return -EINVAL; return -EINVAL;
hash = hashfunc(key, map->size); hash = hashfunc (key, map->size);
if (hash < 0) if (hash < 0)
return hash; return hash;
ptr = map->buckets[hash].head; ptr = map->buckets[hash].head;
while (ptr) { while (ptr)
if (strcasecmp(ptr->key, key) == 0) { {
if (strcasecmp (ptr->key, key) == 0)
{
/* /*
* Found the data, now need to remove everything * Found the data, now need to remove everything
* and update the hashmap. * and update the hashmap.
@ -482,9 +504,9 @@ hashmap_remove(hashmap_t map, const char *key)
if (map->buckets[hash].tail == ptr) if (map->buckets[hash].tail == ptr)
map->buckets[hash].tail = ptr->prev; map->buckets[hash].tail = ptr->prev;
safefree(ptr->key); safefree (ptr->key);
safefree(ptr->data); safefree (ptr->data);
safefree(ptr); safefree (ptr);
++deleted; ++deleted;
--map->end_iterator; --map->end_iterator;

View File

@ -23,7 +23,8 @@
/* Allow the use in C++ code. */ /* Allow the use in C++ code. */
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C"
{
#endif #endif
/* /*
@ -38,8 +39,8 @@ extern "C" {
* hashmap_create() takes one argument, which is the number of buckets to * hashmap_create() takes one argument, which is the number of buckets to
* use internally. hashmap_delete() is self explanatory. * use internally. hashmap_delete() is self explanatory.
*/ */
extern hashmap_t hashmap_create(unsigned int nbuckets); extern hashmap_t hashmap_create (unsigned int nbuckets);
extern int hashmap_delete(hashmap_t map); extern int hashmap_delete (hashmap_t map);
/* /*
* When the you insert a key/data pair into the hashmap it will the key * When the you insert a key/data pair into the hashmap it will the key
@ -50,7 +51,7 @@ extern "C" {
* Returns: negative on error * Returns: negative on error
* 0 upon successful insert * 0 upon successful insert
*/ */
extern int hashmap_insert(hashmap_t map, const char *key, extern int hashmap_insert (hashmap_t map, const char *key,
const void *data, size_t len); const void *data, size_t len);
/* /*
@ -58,7 +59,7 @@ extern "C" {
* *
* Returns: an negative value upon error. * 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. * 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 * Returns: 1 if it is the end
* 0 otherwise * 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 * 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 "iterator" pointing at the first key
* an "end-iterator" if the key wasn't found * 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. * Retrieve the key/data associated with a particular iterator.
@ -86,7 +87,7 @@ extern "C" {
* Returns: the length of the data block upon success * Returns: the length of the data block upon success
* negative upon error * negative upon error
*/ */
extern ssize_t hashmap_return_entry(hashmap_t map, hashmap_iter iter, extern ssize_t hashmap_return_entry (hashmap_t map, hashmap_iter iter,
char **key, void **data); char **key, void **data);
/* /*
@ -97,7 +98,7 @@ extern "C" {
* zero if no entry is found * zero if no entry is found
* length of data for the entry * length of data for the entry
*/ */
extern ssize_t hashmap_entry_by_key(hashmap_t map, const char *key, extern ssize_t hashmap_entry_by_key (hashmap_t map, const char *key,
void **data); void **data);
/* /*
@ -108,7 +109,7 @@ extern "C" {
* zero if no key is found * zero if no key is found
* count found (positive value) * 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. * Go through the hashmap and remove the particular key.
@ -118,7 +119,7 @@ extern "C" {
* 0 if the key was not found * 0 if the key was not found
* positive count of entries deleted * 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) #if defined(__cplusplus)
} }

View File

@ -28,70 +28,71 @@
#include "text.h" #include "text.h"
void * void *
debugging_calloc(size_t nmemb, size_t size, const char *file, debugging_calloc (size_t nmemb, size_t size, const char *file,
unsigned long line) unsigned long line)
{ {
void *ptr; void *ptr;
assert(nmemb > 0); assert (nmemb > 0);
assert(size > 0); assert (size > 0);
ptr = calloc(nmemb, size); ptr = calloc (nmemb, size);
fprintf(stderr, "{calloc: %p:%zu x %zu} %s:%lu\n", ptr, nmemb, size, file, fprintf (stderr, "{calloc: %p:%zu x %zu} %s:%lu\n", ptr, nmemb, size, file,
line); line);
return ptr; return ptr;
} }
void * 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); ptr = malloc (size);
fprintf(stderr, "{malloc: %p:%zu} %s:%lu\n", ptr, size, file, line); fprintf (stderr, "{malloc: %p:%zu} %s:%lu\n", ptr, size, file, line);
return ptr; return ptr;
} }
void * 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); newptr = realloc (ptr, size);
fprintf(stderr, "{realloc: %p -> %p:%zu} %s:%lu\n", ptr, newptr, size, fprintf (stderr, "{realloc: %p -> %p:%zu} %s:%lu\n", ptr, newptr, size,
file, line); file, line);
return newptr; return newptr;
} }
void 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) if (ptr != NULL)
free(ptr); free (ptr);
return; return;
} }
char * 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; char *ptr;
size_t len; size_t len;
assert(s != NULL); assert (s != NULL);
len = strlen(s) + 1; len = strlen (s) + 1;
ptr = malloc(len); ptr = malloc (len);
if (!ptr) if (!ptr)
return NULL; return NULL;
memcpy(ptr, s, len); memcpy (ptr, s, len);
fprintf(stderr, "{strdup: %p:%zu} %s:%lu\n", ptr, len, file, line); fprintf (stderr, "{strdup: %p:%zu} %s:%lu\n", ptr, len, file, line);
return ptr; return ptr;
} }
@ -104,7 +105,7 @@ debugging_strdup(const char *s, const char *file, unsigned long line)
* solution. * solution.
*/ */
void * void *
malloc_shared_memory(size_t size) malloc_shared_memory (size_t size)
{ {
int fd; int fd;
void *ptr; void *ptr;
@ -112,22 +113,22 @@ malloc_shared_memory(size_t size)
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 /* Only allow u+rw bits. This may be required for some versions
* of glibc so that mkstemp() doesn't make us vulnerable. * of glibc so that mkstemp() doesn't make us vulnerable.
*/ */
umask(0177); umask (0177);
if ((fd = mkstemp(buffer)) == -1) if ((fd = mkstemp (buffer)) == -1)
return MAP_FAILED; return MAP_FAILED;
unlink(buffer); unlink (buffer);
if (ftruncate(fd, size) == -1) if (ftruncate (fd, size) == -1)
return MAP_FAILED; return MAP_FAILED;
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 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. * zero.
*/ */
void * void *
calloc_shared_memory(size_t nmemb, size_t size) calloc_shared_memory (size_t nmemb, size_t size)
{ {
void *ptr; void *ptr;
long length; long length;
assert(nmemb > 0); assert (nmemb > 0);
assert(size > 0); assert (size > 0);
length = nmemb * size; length = nmemb * size;
ptr = malloc_shared_memory(length); ptr = malloc_shared_memory (length);
if (ptr == MAP_FAILED) if (ptr == MAP_FAILED)
return ptr; return ptr;
memset(ptr, 0, length); memset (ptr, 0, length);
return ptr; return ptr;
} }

View File

@ -26,14 +26,14 @@
*/ */
#ifndef NDEBUG #ifndef NDEBUG
extern void *debugging_calloc(size_t nmemb, size_t size, const char *file, extern void *debugging_calloc (size_t nmemb, size_t size, const char *file,
unsigned long line); unsigned long line);
extern void *debugging_malloc(size_t size, const char *file, extern void *debugging_malloc (size_t size, const char *file,
unsigned long line); unsigned long line);
extern void debugging_free(void *ptr, const char *file, unsigned long line); extern void debugging_free (void *ptr, const char *file, unsigned long line);
extern void *debugging_realloc(void *ptr, size_t size, const char *file, extern void *debugging_realloc (void *ptr, size_t size, const char *file,
unsigned long line); unsigned long line);
extern char *debugging_strdup(const char *s, const char *file, extern char *debugging_strdup (const char *s, const char *file,
unsigned long line); unsigned long line);
# define safecalloc(x, y) debugging_calloc(x, y, __FILE__, __LINE__) # define safecalloc(x, y) debugging_calloc(x, y, __FILE__, __LINE__)
@ -60,7 +60,7 @@ free(*__safefree_tmp); \
/* /*
* Allocate memory from the "shared" region of memory. * Allocate memory from the "shared" region of memory.
*/ */
extern void *malloc_shared_memory(size_t size); extern void *malloc_shared_memory (size_t size);
extern void *calloc_shared_memory(size_t nmemb, size_t size); extern void *calloc_shared_memory (size_t nmemb, size_t size);
#endif #endif

View File

@ -37,18 +37,18 @@
#define ERRPAGES_BUCKETCOUNT 16 #define ERRPAGES_BUCKETCOUNT 16
int 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); config.errorpages = hashmap_create (ERRPAGES_BUCKETCOUNT);
if (!config.errorpages) if (!config.errorpages)
return (-1); return (-1);
snprintf(errornbuf, ERRORNUM_BUFSIZE, "%u", errornum); snprintf (errornbuf, ERRORNUM_BUFSIZE, "%u", errornum);
if (hashmap_insert(config.errorpages, errornbuf, if (hashmap_insert (config.errorpages, errornbuf,
filepath, strlen(filepath) + 1) < 0) filepath, strlen (filepath) + 1) < 0)
return (-1); return (-1);
return (0); return (0);
@ -58,27 +58,27 @@ add_new_errorpage(char *filepath, unsigned int errornum)
* Get the file appropriate for a given error. * Get the file appropriate for a given error.
*/ */
static char * static char *
get_html_file(unsigned int errornum) get_html_file (unsigned int errornum)
{ {
hashmap_iter result_iter; hashmap_iter result_iter;
char errornbuf[ERRORNUM_BUFSIZE]; char errornbuf[ERRORNUM_BUFSIZE];
char *key; char *key;
static char *val; static char *val;
assert(errornum >= 100 && errornum < 1000); assert (errornum >= 100 && errornum < 1000);
if (!config.errorpages) if (!config.errorpages)
return (config.errorpage_undef); 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)) if (hashmap_is_end (config.errorpages, result_iter))
return (config.errorpage_undef); return (config.errorpage_undef);
if (hashmap_return_entry(config.errorpages, result_iter, if (hashmap_return_entry (config.errorpages, result_iter,
&key, (void **)&val) < 0) &key, (void **) &val) < 0)
return (config.errorpage_undef); return (config.errorpage_undef);
return (val); return (val);
@ -88,19 +88,19 @@ get_html_file(unsigned int errornum)
* Look up the value for a variable. * Look up the value for a variable.
*/ */
static char * static char *
lookup_variable(struct conn_s *connptr, char *varname) lookup_variable (struct conn_s *connptr, char *varname)
{ {
hashmap_iter result_iter; hashmap_iter result_iter;
char *key; char *key;
static char *data; 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)) if (hashmap_is_end (connptr->error_variables, result_iter))
return (NULL); return (NULL);
if (hashmap_return_entry(connptr->error_variables, result_iter, if (hashmap_return_entry (connptr->error_variables, result_iter,
&key, (void **)&data) < 0) &key, (void **) &data) < 0)
return (NULL); return (NULL);
return (data); return (data);
@ -112,33 +112,32 @@ lookup_variable(struct conn_s *connptr, char *varname)
* Send an already-opened file to the client with variable substitution. * Send an already-opened file to the client with variable substitution.
*/ */
int 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 inbuf[HTML_BUFSIZE], *varstart = NULL, *p;
char *varval; char *varval;
int in_variable = 0, writeret; int in_variable = 0, writeret;
while (fgets(inbuf, HTML_BUFSIZE, infile) != NULL) { while (fgets (inbuf, HTML_BUFSIZE, infile) != NULL)
for (p = inbuf; *p; p++) { {
switch (*p) { for (p = inbuf; *p; p++)
{
switch (*p)
{
case '}': case '}':
if (in_variable) { if (in_variable)
{
*p = '\0'; *p = '\0';
if (! if (!(varval = lookup_variable (connptr, varstart)))
(varval =
lookup_variable(connptr,
varstart)))
varval = "(unknown)"; varval = "(unknown)";
writeret = writeret = write_message (connptr->client_fd, "%s", varval);
write_message(connptr->client_fd,
"%s", varval);
if (writeret) if (writeret)
return (writeret); return (writeret);
in_variable = 0; in_variable = 0;
} else { }
writeret = else
write_message(connptr->client_fd, {
"%c", *p); writeret = write_message (connptr->client_fd, "%c", *p);
if (writeret) if (writeret)
return (writeret); return (writeret);
} }
@ -150,16 +149,17 @@ send_html_file(FILE * infile, struct conn_s *connptr)
* this code will fallthrough to the code that * this code will fallthrough to the code that
* just dumps a character to the client fd. * just dumps a character to the client fd.
*/ */
if (!in_variable) { if (!in_variable)
{
varstart = p + 1; varstart = p + 1;
in_variable++; in_variable++;
} else }
else
in_variable = 0; in_variable = 0;
default: default:
if (!in_variable) { if (!in_variable)
writeret = {
write_message(connptr->client_fd, writeret = write_message (connptr->client_fd, "%c", *p);
"%c", *p);
if (writeret) if (writeret)
return (writeret); return (writeret);
} }
@ -172,14 +172,14 @@ send_html_file(FILE * infile, struct conn_s *connptr)
} }
int 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 = char *headers =
"HTTP/1.0 %d %s\r\n" "HTTP/1.0 %d %s\r\n"
"Server: %s/%s\r\n" "Server: %s/%s\r\n"
"Content-Type: text/html\r\n" "Connection: close\r\n" "\r\n"; "Content-Type: text/html\r\n" "Connection: close\r\n" "\r\n";
return (write_message(connptr->client_fd, headers, return (write_message (connptr->client_fd, headers,
code, message, PACKAGE, VERSION)); code, message, PACKAGE, VERSION));
} }
@ -187,7 +187,7 @@ send_http_headers(struct conn_s *connptr, int code, char *message)
* Display an error to the client. * Display an error to the client.
*/ */
int int
send_http_error_message(struct conn_s *connptr) send_http_error_message (struct conn_s *connptr)
{ {
char *error_file; char *error_file;
FILE *infile; FILE *infile;
@ -201,26 +201,23 @@ send_http_error_message(struct conn_s *connptr)
"<h1>%s</h1>\n" "<h1>%s</h1>\n"
"<p>%s</p>\n" "<p>%s</p>\n"
"<hr />\n" "<hr />\n"
"<p><em>Generated by %s version %s.</em></p>\n" "<p><em>Generated by %s version %s.</em></p>\n" "</body>\n" "</html>\n";
"</body>\n"
"</html>\n";
send_http_headers(connptr, connptr->error_number, send_http_headers (connptr, connptr->error_number, connptr->error_string);
connptr->error_string);
error_file = get_html_file(connptr->error_number); error_file = get_html_file (connptr->error_number);
if (!(infile = fopen(error_file, "r"))) { if (!(infile = fopen (error_file, "r")))
char *detail = lookup_variable(connptr, "detail"); {
return (write_message(connptr->client_fd, fallback_error, char *detail = lookup_variable (connptr, "detail");
return (write_message (connptr->client_fd, fallback_error,
connptr->error_number, connptr->error_number,
connptr->error_string, connptr->error_string,
connptr->error_string, connptr->error_string,
detail, detail, PACKAGE, VERSION));
PACKAGE, VERSION));
} }
ret = send_html_file(infile, connptr); ret = send_html_file (infile, connptr);
fclose(infile); fclose (infile);
return (ret); return (ret);
} }
@ -231,16 +228,14 @@ send_http_error_message(struct conn_s *connptr)
#define ERRVAR_BUCKETCOUNT 16 #define ERRVAR_BUCKETCOUNT 16
int 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)
if (! if (!(connptr->error_variables = hashmap_create (ERRVAR_BUCKETCOUNT)))
(connptr->error_variables =
hashmap_create(ERRVAR_BUCKETCOUNT)))
return (-1); return (-1);
return hashmap_insert(connptr->error_variables, key, val, return hashmap_insert (connptr->error_variables, key, val,
strlen(val) + 1); strlen (val) + 1);
} }
#define ADD_VAR_RET(x, y) \ #define ADD_VAR_RET(x, y) \
@ -255,33 +250,33 @@ add_error_variable(struct conn_s *connptr, char *key, char *val)
* Set some standard variables used by all HTML pages * Set some standard variables used by all HTML pages
*/ */
int int
add_standard_vars(struct conn_s *connptr) add_standard_vars (struct conn_s *connptr)
{ {
char errnobuf[16]; char errnobuf[16];
char timebuf[30]; char timebuf[30];
time_t global_time; time_t global_time;
snprintf(errnobuf, sizeof errnobuf, "%d", connptr->error_number); snprintf (errnobuf, sizeof errnobuf, "%d", connptr->error_number);
ADD_VAR_RET("errno", errnobuf); ADD_VAR_RET ("errno", errnobuf);
ADD_VAR_RET("cause", connptr->error_string); ADD_VAR_RET ("cause", connptr->error_string);
ADD_VAR_RET("request", connptr->request_line); ADD_VAR_RET ("request", connptr->request_line);
ADD_VAR_RET("clientip", connptr->client_ip_addr); ADD_VAR_RET ("clientip", connptr->client_ip_addr);
ADD_VAR_RET("clienthost", connptr->client_string_addr); ADD_VAR_RET ("clienthost", connptr->client_string_addr);
/* The following value parts are all non-NULL and will /* The following value parts are all non-NULL and will
* trigger warnings in ADD_VAR_RET(), so we use * trigger warnings in ADD_VAR_RET(), so we use
* add_error_variable() directly. * add_error_variable() directly.
*/ */
global_time = time(NULL); global_time = time (NULL);
strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", strftime (timebuf, sizeof (timebuf), "%a, %d %b %Y %H:%M:%S GMT",
gmtime(&global_time)); gmtime (&global_time));
add_error_variable(connptr, "date", timebuf); add_error_variable (connptr, "date", timebuf);
add_error_variable(connptr, "website", "http://tinyproxy.banu.com/"); add_error_variable (connptr, "website", "http://tinyproxy.banu.com/");
add_error_variable(connptr, "version", VERSION); add_error_variable (connptr, "version", VERSION);
add_error_variable(connptr, "package", PACKAGE); add_error_variable (connptr, "package", PACKAGE);
return (0); return (0);
} }
@ -290,26 +285,28 @@ add_standard_vars(struct conn_s *connptr)
* Add the error information to the conn structure. * Add the error information to the conn structure.
*/ */
int 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; va_list ap;
char *key, *val; char *key, *val;
va_start(ap, message); va_start (ap, message);
while ((key = va_arg(ap, char *))) { while ((key = va_arg (ap, char *)))
val = va_arg(ap, char *); {
val = va_arg (ap, char *);
if (add_error_variable(connptr, key, val) == -1) { if (add_error_variable (connptr, key, val) == -1)
va_end(ap); {
va_end (ap);
return (-1); return (-1);
} }
} }
connptr->error_number = number; connptr->error_number = number;
connptr->error_string = safestrdup(message); connptr->error_string = safestrdup (message);
va_end(ap); va_end (ap);
return (add_standard_vars(connptr)); return (add_standard_vars (connptr));
} }

View File

@ -24,13 +24,14 @@
/* Forward declaration */ /* Forward declaration */
struct conn_s; struct conn_s;
extern int add_new_errorpage(char *filepath, unsigned int errornum); extern int add_new_errorpage (char *filepath, unsigned int errornum);
extern int send_http_error_message(struct conn_s *connptr); extern int send_http_error_message (struct conn_s *connptr);
extern int indicate_http_error(struct conn_s *connptr, int number, extern int indicate_http_error (struct conn_s *connptr, int number,
char *message, ...); char *message, ...);
extern int add_error_variable(struct conn_s *connptr, char *key, char *val); extern int add_error_variable (struct conn_s *connptr, char *key, char *val);
extern int send_html_file(FILE * infile, struct conn_s *connptr); extern int send_html_file (FILE * infile, struct conn_s *connptr);
extern int send_http_headers(struct conn_s *connptr, int code, char *message); extern int send_http_headers (struct conn_s *connptr, int code,
extern int add_standard_vars(struct conn_s *connptr); char *message);
extern int add_standard_vars (struct conn_s *connptr);
#endif /* !TINYPROXY_HTML_ERROR_H */ #endif /* !TINYPROXY_HTML_ERROR_H */

View File

@ -30,9 +30,11 @@
* Also, the caller MUST NOT free the memory while the structure is * Also, the caller MUST NOT free the memory while the structure is
* still in use---bad things would happen. * still in use---bad things would happen.
*/ */
struct http_message_s { struct http_message_s
{
/* Response string and code supplied on the HTTP status line */ /* Response string and code supplied on the HTTP status line */
struct { struct
{
const char *string; const char *string;
int code; int code;
} response; } response;
@ -42,14 +44,16 @@ struct http_message_s {
* the strings are referenced through pointers in an array. * the strings are referenced through pointers in an array.
* I might change this to a vector in the future. * I might change this to a vector in the future.
*/ */
struct { struct
{
char **strings; char **strings;
unsigned int total; unsigned int total;
unsigned int used; unsigned int used;
} headers; } headers;
/* Body of the message (most likely an HTML message) */ /* Body of the message (most likely an HTML message) */
struct { struct
{
const char *text; const char *text;
size_t length; size_t length;
} body; } body;
@ -61,7 +65,7 @@ struct http_message_s {
* number is returned. Useful for if() tests and assert() tests. * number is returned. Useful for if() tests and assert() tests.
*/ */
static int static int
is_http_message_valid(http_message_t msg) is_http_message_valid (http_message_t msg)
{ {
if (msg == NULL) if (msg == NULL)
return 0; return 0;
@ -83,28 +87,30 @@ is_http_message_valid(http_message_t msg)
* If memory could not be allocated, return a NULL. * If memory could not be allocated, return a NULL.
*/ */
http_message_t 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; http_message_t msg;
int ret; int ret;
msg = safecalloc(1, sizeof(struct http_message_s)); msg = safecalloc (1, sizeof (struct http_message_s));
if (msg == NULL) if (msg == NULL)
return NULL; return NULL;
msg->headers.strings = safecalloc(NUMBER_OF_HEADERS, sizeof(char *)); msg->headers.strings = safecalloc (NUMBER_OF_HEADERS, sizeof (char *));
if (msg->headers.strings == NULL) { if (msg->headers.strings == NULL)
safefree(msg); {
safefree (msg);
return NULL; return NULL;
} }
msg->headers.total = NUMBER_OF_HEADERS; msg->headers.total = NUMBER_OF_HEADERS;
/* Store the HTTP response information in the structure */ /* Store the HTTP response information in the structure */
ret = http_message_set_response(msg, response_code, response_string); ret = http_message_set_response (msg, response_code, response_string);
if (IS_HTTP_MSG_ERROR(ret)) { if (IS_HTTP_MSG_ERROR (ret))
safefree(msg->headers.strings); {
safefree(msg); safefree (msg->headers.strings);
safefree (msg);
return NULL; return NULL;
} }
@ -117,18 +123,18 @@ http_message_create(int response_code, const char *response_string)
* is the responsibility of the caller. * is the responsibility of the caller.
*/ */
int int
http_message_destroy(http_message_t msg) http_message_destroy (http_message_t msg)
{ {
assert(msg != NULL); assert (msg != NULL);
assert(msg->headers.strings != NULL); assert (msg->headers.strings != NULL);
/* Check for valid arguments */ /* Check for valid arguments */
if (msg == NULL) if (msg == NULL)
return -EFAULT; return -EFAULT;
if (msg->headers.strings != NULL) if (msg->headers.strings != NULL)
safefree(msg->headers.strings); safefree (msg->headers.strings);
safefree(msg); safefree (msg);
return 0; return 0;
} }
@ -137,7 +143,7 @@ http_message_destroy(http_message_t msg)
* must be a NUL ('\0') terminated C string. * must be a NUL ('\0') terminated C string.
*/ */
int int
http_message_set_response(http_message_t msg, http_message_set_response (http_message_t msg,
int response_code, const char *response_string) int response_code, const char *response_string)
{ {
/* Check for valid arguments */ /* Check for valid arguments */
@ -147,7 +153,7 @@ http_message_set_response(http_message_t msg,
return -EINVAL; return -EINVAL;
if (response_string == NULL) if (response_string == NULL)
return -EINVAL; return -EINVAL;
if (strlen(response_string) == 0) if (strlen (response_string) == 0)
return -EINVAL; return -EINVAL;
msg->response.code = response_code; msg->response.code = response_code;
@ -160,7 +166,7 @@ http_message_set_response(http_message_t msg,
* Set the HTTP message body. * Set the HTTP message body.
*/ */
int 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 */ /* Check for valid arguments */
if (msg == NULL) if (msg == NULL)
@ -180,7 +186,7 @@ http_message_set_body(http_message_t msg, const char *body, size_t len)
* Add headers to the structure. * Add headers to the structure.
*/ */
int 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; char **new_headers;
int i; int i;
@ -197,9 +203,9 @@ http_message_add_headers(http_message_t msg, char **headers, int num_headers)
* If the number of headers to add is greater than the space * If the number of headers to add is greater than the space
* available, reallocate the memory. * available, reallocate the memory.
*/ */
if (msg->headers.used + num_headers > msg->headers.total) { if (msg->headers.used + num_headers > msg->headers.total)
new_headers = safecalloc(msg->headers.total * 2, {
sizeof(char *)); new_headers = safecalloc (msg->headers.total * 2, sizeof (char *));
if (new_headers == NULL) if (new_headers == NULL)
return -ENOMEM; return -ENOMEM;
@ -208,7 +214,7 @@ http_message_add_headers(http_message_t msg, char **headers, int num_headers)
new_headers[i] = msg->headers.strings[i]; new_headers[i] = msg->headers.strings[i];
/* Remove the old array and replace it with the new array */ /* Remove the old array and replace it with the new array */
safefree(msg->headers.strings); safefree (msg->headers.strings);
msg->headers.strings = new_headers; msg->headers.strings = new_headers;
msg->headers.total *= 2; msg->headers.total *= 2;
} }
@ -227,45 +233,45 @@ http_message_add_headers(http_message_t msg, char **headers, int num_headers)
* Send the completed HTTP message via the supplied file descriptor. * Send the completed HTTP message via the supplied file descriptor.
*/ */
int int
http_message_send(http_message_t msg, int fd) http_message_send (http_message_t msg, int fd)
{ {
char timebuf[30]; char timebuf[30];
time_t global_time; time_t global_time;
unsigned int i; unsigned int i;
assert(is_http_message_valid(msg)); assert (is_http_message_valid (msg));
/* Check for valid arguments */ /* Check for valid arguments */
if (msg == NULL) if (msg == NULL)
return -EFAULT; return -EFAULT;
if (fd < 1) if (fd < 1)
return -EBADF; return -EBADF;
if (!is_http_message_valid(msg)) if (!is_http_message_valid (msg))
return -EINVAL; return -EINVAL;
/* Write the response line */ /* Write the response line */
write_message(fd, "HTTP/1.0 %d %s\r\n", write_message (fd, "HTTP/1.0 %d %s\r\n",
msg->response.code, msg->response.string); msg->response.code, msg->response.string);
/* Go through all the headers */ /* Go through all the headers */
for (i = 0; i != msg->headers.used; ++i) for (i = 0; i != msg->headers.used; ++i)
write_message(fd, "%s\r\n", msg->headers.strings[i]); write_message (fd, "%s\r\n", msg->headers.strings[i]);
/* Output the date */ /* Output the date */
global_time = time(NULL); global_time = time (NULL);
strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", strftime (timebuf, sizeof (timebuf), "%a, %d %b %Y %H:%M:%S GMT",
gmtime(&global_time)); gmtime (&global_time));
write_message(fd, "Date: %s\r\n", timebuf); write_message (fd, "Date: %s\r\n", timebuf);
/* Output the content-length */ /* Output the content-length */
write_message(fd, "Content-length: %u\r\n", msg->body.length); write_message (fd, "Content-length: %u\r\n", msg->body.length);
/* Write the separator between the headers and body */ /* Write the separator between the headers and body */
safe_write(fd, "\r\n", 2); safe_write (fd, "\r\n", 2);
/* If there's a body, send it! */ /* If there's a body, send it! */
if (msg->body.length > 0) if (msg->body.length > 0)
safe_write(fd, msg->body.text, msg->body.length); safe_write (fd, msg->body.text, msg->body.length);
return 0; return 0;
} }

View File

@ -58,26 +58,26 @@ typedef struct http_message_s *http_message_t;
#define IS_HTTP_MSG_ERROR(x) (x < 0) #define IS_HTTP_MSG_ERROR(x) (x < 0)
/* Initialize the internal structure of the HTTP message */ /* Initialize the internal structure of the HTTP message */
extern http_message_t http_message_create(int response_code, extern http_message_t http_message_create (int response_code,
const char *response_string); const char *response_string);
/* Free up an _internal_ resources */ /* 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 * Send an HTTP message via the supplied file descriptor. This function
* will add the "Date" header before it's sent. * 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 * Change the internal state of the HTTP message. Either set the
* body of the message, update the response information, or * body of the message, update the response information, or
* add a new set of headers. * add a new set of headers.
*/ */
extern int http_message_set_body(http_message_t msg, extern int http_message_set_body (http_message_t msg,
const char *body, size_t len); const char *body, size_t len);
extern int http_message_set_response(http_message_t msg, extern int http_message_set_response (http_message_t msg,
int response_code, int response_code,
const char *response_string); const char *response_string);
@ -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 * line-feeds (LF) since they will be included when the http_message is
* sent. * sent.
*/ */
extern int http_message_add_headers(http_message_t msg, extern int http_message_add_headers (http_message_t msg,
char **headers, int num_headers); char **headers, int num_headers);
#endif /* _TINYPROXY_HTTP_MESSAGE_H_ */ #endif /* _TINYPROXY_HTTP_MESSAGE_H_ */

110
src/log.c
View File

@ -65,9 +65,9 @@ static vector_t log_message_storage;
* Open the log file and store the file descriptor in a global location. * Open the log file and store the file descriptor in a global location.
*/ */
int 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); log_file_fd = create_file_safely (log_file_name, FALSE);
return log_file_fd; return log_file_fd;
} }
@ -75,26 +75,26 @@ open_log_file(const char *log_file_name)
* Close the log file * Close the log file
*/ */
void void
close_log_file(void) close_log_file (void)
{ {
close(log_file_fd); close (log_file_fd);
} }
/* /*
* Truncate log file to a zero length. * Truncate log file to a zero length.
*/ */
void void
truncate_log_file(void) truncate_log_file (void)
{ {
lseek(log_file_fd, 0, SEEK_SET); lseek (log_file_fd, 0, SEEK_SET);
ftruncate(log_file_fd, 0); ftruncate (log_file_fd, 0);
} }
/* /*
* Set the log level for writing to the log file. * Set the log level for writing to the log file.
*/ */
void void
set_log_level(int level) set_log_level (int level)
{ {
log_level = level; log_level = level;
} }
@ -103,7 +103,7 @@ set_log_level(int level)
* This routine logs messages to either the log file or the syslog function. * This routine logs messages to either the log file or the syslog function.
*/ */
void void
log_message(int level, char *fmt, ...) log_message (int level, char *fmt, ...)
{ {
va_list args; va_list args;
time_t nowtime; time_t nowtime;
@ -115,13 +115,17 @@ log_message(int level, char *fmt, ...)
/* /*
* Figure out if we should write the message or not. * Figure out if we should write the message or not.
*/ */
if (log_level == LOG_CONN) { if (log_level == LOG_CONN)
{
if (level == LOG_INFO) if (level == LOG_INFO)
return; return;
} else if (log_level == LOG_INFO) { }
else if (log_level == LOG_INFO)
{
if (level > LOG_INFO && level != LOG_CONN) if (level > LOG_INFO && level != LOG_CONN)
return; return;
} else if (level > log_level) }
else if (level > log_level)
return; return;
#endif #endif
@ -130,73 +134,78 @@ log_message(int level, char *fmt, ...)
level = LOG_INFO; level = LOG_INFO;
#endif #endif
va_start(args, fmt); va_start (args, fmt);
/* /*
* If the config file hasn't been processed, then we need to store * If the config file hasn't been processed, then we need to store
* the messages for later processing. * the messages for later processing.
*/ */
if (!processed_config_file) { if (!processed_config_file)
{
char *entry_buffer; char *entry_buffer;
if (!log_message_storage) { if (!log_message_storage)
log_message_storage = vector_create(); {
log_message_storage = vector_create ();
if (!log_message_storage) if (!log_message_storage)
goto out; goto out;
} }
vsnprintf(str, STRING_LENGTH, fmt, args); vsnprintf (str, STRING_LENGTH, fmt, args);
entry_buffer = safemalloc(strlen(str) + 6); entry_buffer = safemalloc (strlen (str) + 6);
if (!entry_buffer) if (!entry_buffer)
goto out; goto out;
sprintf(entry_buffer, "%d %s", level, str); sprintf (entry_buffer, "%d %s", level, str);
vector_append(log_message_storage, entry_buffer, vector_append (log_message_storage, entry_buffer,
strlen(entry_buffer) + 1); strlen (entry_buffer) + 1);
safefree(entry_buffer); safefree (entry_buffer);
goto out; goto out;
} }
#ifdef HAVE_SYSLOG_H #ifdef HAVE_SYSLOG_H
if (config.syslog) { if (config.syslog)
{
# ifdef HAVE_VSYSLOG_H # ifdef HAVE_VSYSLOG_H
vsyslog(level, fmt, args); vsyslog (level, fmt, args);
# else # else
vsnprintf(str, STRING_LENGTH, fmt, args); vsnprintf (str, STRING_LENGTH, fmt, args);
syslog(level, "%s", str); syslog (level, "%s", str);
# endif # endif
} else { }
else
{
#endif #endif
nowtime = time(NULL); nowtime = time (NULL);
/* Format is month day hour:minute:second (24 time) */ /* Format is month day hour:minute:second (24 time) */
strftime(time_string, TIME_LENGTH, "%b %d %H:%M:%S", strftime (time_string, TIME_LENGTH, "%b %d %H:%M:%S",
localtime(&nowtime)); localtime (&nowtime));
snprintf(str, STRING_LENGTH, "%-9s %s [%ld]: ", snprintf (str, STRING_LENGTH, "%-9s %s [%ld]: ",
syslog_level[level], time_string, (long int)getpid()); 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)); write (log_file_fd, str, strlen (str));
vsnprintf(str, STRING_LENGTH, fmt, args); vsnprintf (str, STRING_LENGTH, fmt, args);
write(log_file_fd, str, strlen(str)); write (log_file_fd, str, strlen (str));
write(log_file_fd, "\n", 1); write (log_file_fd, "\n", 1);
fsync(log_file_fd); fsync (log_file_fd);
#ifdef HAVE_SYSLOG_H #ifdef HAVE_SYSLOG_H
} }
#endif #endif
out: out:
va_end(args); va_end (args);
} }
/* /*
* This needs to send any stored log messages. * This needs to send any stored log messages.
*/ */
void void
send_stored_logs(void) send_stored_logs (void)
{ {
char *string; char *string;
char *ptr; char *ptr;
@ -205,25 +214,28 @@ send_stored_logs(void)
size_t i; size_t i;
for (i = 0; i != vector_length(log_message_storage); ++i) { for (i = 0; i != vector_length (log_message_storage); ++i)
string = vector_getentry(log_message_storage, i, NULL); {
string = vector_getentry (log_message_storage, i, NULL);
ptr = strchr(string, ' ') + 1; ptr = strchr (string, ' ') + 1;
level = atoi(string); level = atoi (string);
#ifdef NDEBUG #ifdef NDEBUG
if (log_level == LOG_CONN && level == LOG_INFO) if (log_level == LOG_CONN && level == LOG_INFO)
continue; continue;
else if (log_level == LOG_INFO) { else if (log_level == LOG_INFO)
{
if (level > LOG_INFO && level != LOG_CONN) if (level > LOG_INFO && level != LOG_CONN)
continue; continue;
} else if (level > log_level) }
else if (level > log_level)
continue; continue;
#endif #endif
log_message(level, ptr); log_message (level, ptr);
} }
vector_delete(log_message_storage); vector_delete (log_message_storage);
log_message_storage = NULL; log_message_storage = NULL;
} }

View File

@ -102,12 +102,12 @@
# define DEBUG2(x, y...) do { } while(0) # define DEBUG2(x, y...) do { } while(0)
#endif #endif
extern int open_log_file(const char *file); extern int open_log_file (const char *file);
extern void close_log_file(void); extern void close_log_file (void);
extern void truncate_log_file(void); extern void truncate_log_file (void);
extern void log_message(int level, char *fmt, ...); extern void log_message (int level, char *fmt, ...);
extern void set_log_level(int level); extern void set_log_level (int level);
extern void send_stored_logs(void); extern void send_stored_logs (void);
#endif #endif

View File

@ -33,21 +33,23 @@
* again. Keep sending until the buffer has been sent. * again. Keep sending until the buffer has been sent.
*/ */
ssize_t 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; ssize_t len;
size_t bytestosend; size_t bytestosend;
assert(fd >= 0); assert (fd >= 0);
assert(buffer != NULL); assert (buffer != NULL);
assert(count > 0); assert (count > 0);
bytestosend = count; bytestosend = count;
while (1) { while (1)
len = send(fd, buffer, bytestosend, MSG_NOSIGNAL); {
len = send (fd, buffer, bytestosend, MSG_NOSIGNAL);
if (len < 0) { if (len < 0)
{
if (errno == EINTR) if (errno == EINTR)
continue; continue;
else else
@ -69,13 +71,15 @@ safe_write(int fd, const char *buffer, size_t count)
* again. * again.
*/ */
ssize_t 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 { do
len = read(fd, buffer, count); {
} while (len < 0 && errno == EINTR); len = read (fd, buffer, count);
}
while (len < 0 && errno == EINTR);
return len; return len;
} }
@ -87,20 +91,21 @@ safe_read(int fd, char *buffer, size_t count)
* (although I did fix a memory leak. :) * (although I did fix a memory leak. :)
*/ */
int int
write_message(int fd, const char *fmt, ...) write_message (int fd, const char *fmt, ...)
{ {
ssize_t n; ssize_t n;
size_t size = (1024 * 8); /* start with 8 KB and go from there */ size_t size = (1024 * 8); /* start with 8 KB and go from there */
char *buf, *tmpbuf; char *buf, *tmpbuf;
va_list ap; va_list ap;
if ((buf = safemalloc(size)) == NULL) if ((buf = safemalloc (size)) == NULL)
return -1; return -1;
while (1) { while (1)
va_start(ap, fmt); {
n = vsnprintf(buf, size, fmt, ap); va_start (ap, fmt);
va_end(ap); n = vsnprintf (buf, size, fmt, ap);
va_end (ap);
/* If that worked, break out so we can send the buffer */ /* If that worked, break out so we can send the buffer */
if (n > -1 && n < size) if (n > -1 && n < size)
@ -114,19 +119,22 @@ write_message(int fd, const char *fmt, ...)
/* twice the old size (glibc2.0) */ /* twice the old size (glibc2.0) */
size *= 2; size *= 2;
if ((tmpbuf = saferealloc(buf, size)) == NULL) { if ((tmpbuf = saferealloc (buf, size)) == NULL)
safefree(buf); {
safefree (buf);
return -1; return -1;
} else }
else
buf = tmpbuf; buf = tmpbuf;
} }
if (safe_write(fd, buf, n) < 0) { if (safe_write (fd, buf, n) < 0)
safefree(buf); {
safefree (buf);
return -1; return -1;
} }
safefree(buf); safefree (buf);
return 0; return 0;
} }
@ -142,7 +150,7 @@ write_message(int fd, const char *fmt, ...)
#define SEGMENT_LEN (512) #define SEGMENT_LEN (512)
#define MAXIMUM_BUFFER_LENGTH (128 * 1024) #define MAXIMUM_BUFFER_LENGTH (128 * 1024)
ssize_t ssize_t
readline(int fd, char **whole_buffer) readline (int fd, char **whole_buffer)
{ {
ssize_t whole_buffer_len; ssize_t whole_buffer_len;
char buffer[SEGMENT_LEN]; char buffer[SEGMENT_LEN];
@ -151,26 +159,28 @@ readline(int fd, char **whole_buffer)
ssize_t ret; ssize_t ret;
ssize_t diff; ssize_t diff;
struct read_lines_s { struct read_lines_s
{
char *data; char *data;
size_t len; size_t len;
struct read_lines_s *next; struct read_lines_s *next;
}; };
struct read_lines_s *first_line, *line_ptr; struct read_lines_s *first_line, *line_ptr;
first_line = safecalloc(sizeof(struct read_lines_s), 1); first_line = safecalloc (sizeof (struct read_lines_s), 1);
if (!first_line) if (!first_line)
return -ENOMEM; return -ENOMEM;
line_ptr = first_line; line_ptr = first_line;
whole_buffer_len = 0; whole_buffer_len = 0;
for (;;) { for (;;)
ret = recv(fd, buffer, SEGMENT_LEN, MSG_PEEK); {
ret = recv (fd, buffer, SEGMENT_LEN, MSG_PEEK);
if (ret <= 0) if (ret <= 0)
goto CLEANUP; goto CLEANUP;
ptr = memchr(buffer, '\n', ret); ptr = memchr (buffer, '\n', ret);
if (ptr) if (ptr)
diff = ptr - buffer + 1; diff = ptr - buffer + 1;
else else
@ -182,35 +192,40 @@ readline(int fd, char **whole_buffer)
* Don't allow the buffer to grow without bound. If we * Don't allow the buffer to grow without bound. If we
* get to more than MAXIMUM_BUFFER_LENGTH close. * get to more than MAXIMUM_BUFFER_LENGTH close.
*/ */
if (whole_buffer_len > MAXIMUM_BUFFER_LENGTH) { if (whole_buffer_len > MAXIMUM_BUFFER_LENGTH)
{
ret = -ERANGE; ret = -ERANGE;
goto CLEANUP; goto CLEANUP;
} }
line_ptr->data = safemalloc(diff); line_ptr->data = safemalloc (diff);
if (!line_ptr->data) { if (!line_ptr->data)
{
ret = -ENOMEM; ret = -ENOMEM;
goto CLEANUP; goto CLEANUP;
} }
recv(fd, line_ptr->data, diff, 0); recv (fd, line_ptr->data, diff, 0);
line_ptr->len = diff; line_ptr->len = diff;
if (ptr) { if (ptr)
{
line_ptr->next = NULL; line_ptr->next = NULL;
break; break;
} }
line_ptr->next = safecalloc(sizeof(struct read_lines_s), 1); line_ptr->next = safecalloc (sizeof (struct read_lines_s), 1);
if (!line_ptr->next) { if (!line_ptr->next)
{
ret = -ENOMEM; ret = -ENOMEM;
goto CLEANUP; goto CLEANUP;
} }
line_ptr = line_ptr->next; line_ptr = line_ptr->next;
} }
*whole_buffer = safemalloc(whole_buffer_len + 1); *whole_buffer = safemalloc (whole_buffer_len + 1);
if (!*whole_buffer) { if (!*whole_buffer)
{
ret = -ENOMEM; ret = -ENOMEM;
goto CLEANUP; goto CLEANUP;
} }
@ -219,8 +234,9 @@ readline(int fd, char **whole_buffer)
whole_buffer_len = 0; whole_buffer_len = 0;
line_ptr = first_line; line_ptr = first_line;
while (line_ptr) { while (line_ptr)
memcpy(*whole_buffer + whole_buffer_len, line_ptr->data, {
memcpy (*whole_buffer + whole_buffer_len, line_ptr->data,
line_ptr->len); line_ptr->len);
whole_buffer_len += line_ptr->len; whole_buffer_len += line_ptr->len;
@ -229,14 +245,16 @@ readline(int fd, char **whole_buffer)
ret = whole_buffer_len; ret = whole_buffer_len;
CLEANUP: CLEANUP:
do { do
{
line_ptr = first_line->next; line_ptr = first_line->next;
if (first_line->data) if (first_line->data)
safefree(first_line->data); safefree (first_line->data);
safefree(first_line); safefree (first_line);
first_line = line_ptr; first_line = line_ptr;
} while (first_line); }
while (first_line);
return ret; return ret;
} }
@ -246,24 +264,27 @@ readline(int fd, char **whole_buffer)
* hex string. * hex string.
*/ */
char * 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 (sa != NULL);
assert(buf != NULL); assert (buf != NULL);
assert(buflen != 0); assert (buflen != 0);
buf[0] = '\0'; /* start with an empty string */ buf[0] = '\0'; /* start with an empty string */
switch (sa->sa_family) { switch (sa->sa_family)
case AF_INET:{ {
struct sockaddr_in *sa_in = (struct sockaddr_in *)sa; case AF_INET:
{
struct sockaddr_in *sa_in = (struct sockaddr_in *) sa;
inet_ntop(AF_INET, &sa_in->sin_addr, buf, buflen); inet_ntop (AF_INET, &sa_in->sin_addr, buf, buflen);
break; break;
} }
case AF_INET6:{ case AF_INET6:
struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)sa; {
struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *) sa;
inet_ntop(AF_INET6, &sa_in6->sin6_addr, buf, buflen); inet_ntop (AF_INET6, &sa_in6->sin6_addr, buf, buflen);
break; break;
} }
default: default:
@ -282,28 +303,29 @@ get_ip_string(struct sockaddr *sa, char *buf, size_t buflen)
* Returns the same as inet_pton(). * Returns the same as inet_pton().
*/ */
int 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 */ char buf[24], tmp[24]; /* IPv4->IPv6 = ::FFFF:xxx.xxx.xxx.xxx\0 */
int n; int n;
assert(ip != NULL && strlen(ip) != 0); assert (ip != NULL && strlen (ip) != 0);
assert(dst != NULL); assert (dst != NULL);
/* /*
* Check if the string is an IPv4 numeric address. We use the * Check if the string is an IPv4 numeric address. We use the
* older inet_aton() call since it handles more IPv4 numeric * older inet_aton() call since it handles more IPv4 numeric
* address formats. * address formats.
*/ */
n = inet_aton(ip, (struct in_addr *)dst); n = inet_aton (ip, (struct in_addr *) dst);
if (n == 0) { if (n == 0)
{
/* /*
* Simple case: "ip" wasn't an IPv4 numeric address, so * Simple case: "ip" wasn't an IPv4 numeric address, so
* try doing the conversion as an IPv6 address. This * try doing the conversion as an IPv6 address. This
* will either succeed or fail, but we can't do any * will either succeed or fail, but we can't do any
* more processing anyway. * more processing anyway.
*/ */
return inet_pton(AF_INET6, ip, dst); return inet_pton (AF_INET6, ip, dst);
} }
/* /*
@ -316,7 +338,7 @@ full_inet_pton(const char *ip, void *dst)
* so we can be sure that inet_pton will accept the * so we can be sure that inet_pton will accept the
* full string. * full string.
*/ */
snprintf(buf, sizeof(buf), "::ffff:%s", snprintf (buf, sizeof (buf), "::ffff:%s",
inet_ntop(AF_INET, dst, tmp, sizeof(tmp))); inet_ntop (AF_INET, dst, tmp, sizeof (tmp)));
return inet_pton(AF_INET6, buf, dst); return inet_pton (AF_INET6, buf, dst);
} }

View File

@ -21,13 +21,13 @@
#ifndef TINYPROXY_NETWORK_H #ifndef TINYPROXY_NETWORK_H
#define TINYPROXY_NETWORK_H #define TINYPROXY_NETWORK_H
extern ssize_t safe_write(int fd, const 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 ssize_t safe_read (int fd, char *buffer, size_t count);
extern int write_message(int fd, const char *fmt, ...); extern int write_message (int fd, const char *fmt, ...);
extern ssize_t readline(int fd, char **whole_buffer); extern ssize_t readline (int fd, char **whole_buffer);
extern char *get_ip_string(struct sockaddr *sa, char *buf, size_t len); extern char *get_ip_string (struct sockaddr *sa, char *buf, size_t len);
extern int full_inet_pton(const char *ip, void *dst); extern int full_inet_pton (const char *ip, void *dst);
#endif #endif

1061
src/reqs.c

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,8 @@
/* /*
* This structure holds the information pulled from a URL request. * This structure holds the information pulled from a URL request.
*/ */
struct request_s { struct request_s
{
char *method; char *method;
char *protocol; char *protocol;
@ -44,8 +45,8 @@ struct request_s {
char *path; char *path;
}; };
extern void handle_connection(int fd); extern void handle_connection (int fd);
extern void add_connect_port_allowed(int port); extern void add_connect_port_allowed (int port);
extern void upstream_add(const char *host, int port, const char *domain); extern void upstream_add (const char *host, int port, const char *domain);
#endif #endif

View File

@ -30,47 +30,49 @@
* Add entry to the reversepath list * Add entry to the reversepath list
*/ */
void void
reversepath_add(const char *path, const char *url) reversepath_add (const char *path, const char *url)
{ {
struct reversepath *reverse; struct reversepath *reverse;
if (url == NULL) { if (url == NULL)
log_message(LOG_WARNING, {
"Illegal reverse proxy rule: missing url"); log_message (LOG_WARNING, "Illegal reverse proxy rule: missing url");
return; return;
} }
if (!strstr(url, "://")) { if (!strstr (url, "://"))
log_message(LOG_WARNING, {
log_message (LOG_WARNING,
"Skipping reverse proxy rule: '%s' is not a valid url", "Skipping reverse proxy rule: '%s' is not a valid url",
url); url);
return; return;
} }
if (path && *path != '/') { if (path && *path != '/')
log_message(LOG_WARNING, {
log_message (LOG_WARNING,
"Skipping reverse proxy rule: path '%s' doesn't start with a /", "Skipping reverse proxy rule: path '%s' doesn't start with a /",
path); path);
return; return;
} }
if (!(reverse = safemalloc(sizeof(struct reversepath)))) { if (!(reverse = safemalloc (sizeof (struct reversepath))))
log_message(LOG_ERR, {
"Unable to allocate memory in reversepath_add()"); log_message (LOG_ERR, "Unable to allocate memory in reversepath_add()");
return; return;
} }
if (!path) if (!path)
reverse->path = safestrdup("/"); reverse->path = safestrdup ("/");
else else
reverse->path = safestrdup(path); reverse->path = safestrdup (path);
reverse->url = safestrdup(url); reverse->url = safestrdup (url);
reverse->next = config.reversepath_list; reverse->next = config.reversepath_list;
config.reversepath_list = reverse; config.reversepath_list = reverse;
log_message(LOG_INFO, log_message (LOG_INFO,
"Added reverse proxy rule: %s -> %s", reverse->path, "Added reverse proxy rule: %s -> %s", reverse->path,
reverse->url); reverse->url);
} }
@ -79,12 +81,13 @@ reversepath_add(const char *path, const char *url)
* Check if a request url is in the reversepath list * Check if a request url is in the reversepath list
*/ */
struct reversepath * struct reversepath *
reversepath_get(char *url) reversepath_get (char *url)
{ {
struct reversepath *reverse = config.reversepath_list; struct reversepath *reverse = config.reversepath_list;
while (reverse) { while (reverse)
if (strstr(url, reverse->path) == url) {
if (strstr (url, reverse->path) == url)
return reverse; return reverse;
reverse = reverse->next; reverse = reverse->next;
@ -97,7 +100,8 @@ reversepath_get(char *url)
* Rewrite the URL for reverse proxying. * Rewrite the URL for reverse proxying.
*/ */
char * 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 *rewrite_url = NULL;
char *cookie = NULL; char *cookie = NULL;
@ -105,53 +109,53 @@ reverse_rewrite_url(struct conn_s *connptr, hashmap_t hashofheaders, char *url)
struct reversepath *reverse; struct reversepath *reverse;
/* Reverse requests always start with a slash */ /* Reverse requests always start with a slash */
if (*url == '/') { if (*url == '/')
{
/* First try locating the reverse mapping by request url */ /* First try locating the reverse mapping by request url */
reverse = reversepath_get(url); reverse = reversepath_get (url);
if (reverse) { if (reverse)
rewrite_url = safemalloc(strlen(url) + {
strlen(reverse->url) + 1); rewrite_url = safemalloc (strlen (url) + strlen (reverse->url) + 1);
strcpy(rewrite_url, reverse->url); strcpy (rewrite_url, reverse->url);
strcat(rewrite_url, url + strlen(reverse->path)); strcat (rewrite_url, url + strlen (reverse->path));
} else if (config.reversemagic }
&& hashmap_entry_by_key(hashofheaders, else if (config.reversemagic
"cookie", && hashmap_entry_by_key (hashofheaders,
(void **)&cookie) > 0) { "cookie", (void **) &cookie) > 0)
{
/* No match - try the magical tracking cookie next */ /* No match - try the magical tracking cookie next */
if ((cookieval = strstr(cookie, REVERSE_COOKIE "=")) if ((cookieval = strstr (cookie, REVERSE_COOKIE "="))
&& (reverse = && (reverse =
reversepath_get(cookieval + reversepath_get (cookieval + strlen (REVERSE_COOKIE) + 1)))
strlen(REVERSE_COOKIE) + 1))) { {
rewrite_url = safemalloc(strlen(url) + rewrite_url = safemalloc (strlen (url) +
strlen strlen (reverse->url) + 1);
(reverse->url) + 1); strcpy (rewrite_url, reverse->url);
strcpy(rewrite_url, reverse->url); strcat (rewrite_url, url + 1);
strcat(rewrite_url, url + 1);
log_message(LOG_INFO, log_message (LOG_INFO,
"Magical tracking cookie says: %s", "Magical tracking cookie says: %s", reverse->path);
reverse->path);
} }
} }
} }
/* Forward proxy support off and no reverse path match found */ /* Forward proxy support off and no reverse path match found */
if (config.reverseonly && !rewrite_url) { if (config.reverseonly && !rewrite_url)
log_message(LOG_ERR, "Bad request"); {
indicate_http_error(connptr, 400, "Bad Request", log_message (LOG_ERR, "Bad request");
indicate_http_error (connptr, 400, "Bad Request",
"detail", "detail",
"Request has an invalid URL", "url", "Request has an invalid URL", "url", url, NULL);
url, NULL);
return NULL; return NULL;
} }
log_message(LOG_CONN, "Rewriting URL: %s -> %s", url, rewrite_url); log_message (LOG_CONN, "Rewriting URL: %s -> %s", url, rewrite_url);
/* Store reverse path so that the magical tracking cookie can be set */ /* Store reverse path so that the magical tracking cookie can be set */
if (config.reversemagic) if (config.reversemagic)
connptr->reversepath = safestrdup(reverse->path); connptr->reversepath = safestrdup (reverse->path);
return rewrite_url; return rewrite_url;
} }

View File

@ -23,7 +23,8 @@
#include "conns.h" #include "conns.h"
struct reversepath { struct reversepath
{
struct reversepath *next; struct reversepath *next;
char *path; char *path;
char *url; char *url;
@ -31,9 +32,9 @@ struct reversepath {
#define REVERSE_COOKIE "yummy_magical_cookie" #define REVERSE_COOKIE "yummy_magical_cookie"
extern void reversepath_add(const char *path, const char *url); extern void reversepath_add (const char *path, const char *url);
extern struct reversepath *reversepath_get(char *url); extern struct reversepath *reversepath_get (char *url);
extern char *reverse_rewrite_url(struct conn_s *connptr, extern char *reverse_rewrite_url (struct conn_s *connptr,
hashmap_t hashofheaders, char *url); hashmap_t hashofheaders, char *url);
#endif #endif

View File

@ -39,30 +39,32 @@
* to indicate an error. * to indicate an error.
*/ */
static int 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 (sockfd >= 0);
assert(addr != NULL && strlen(addr) != 0); assert (addr != NULL && strlen (addr) != 0);
memset(&hints, 0, sizeof(struct addrinfo)); memset (&hints, 0, sizeof (struct addrinfo));
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
/* The local port it not important */ /* The local port it not important */
if (getaddrinfo(addr, NULL, &hints, &res) != 0) if (getaddrinfo (addr, NULL, &hints, &res) != 0)
return -1; return -1;
ressave = res; ressave = res;
/* Loop through the addresses and try to bind to each */ /* Loop through the addresses and try to bind to each */
do { do
if (bind(sockfd, res->ai_addr, res->ai_addrlen) == 0) {
if (bind (sockfd, res->ai_addr, res->ai_addrlen) == 0)
break; /* success */ break; /* success */
} while ((res = res->ai_next) != NULL); }
while ((res = res->ai_next) != NULL);
freeaddrinfo(ressave); freeaddrinfo (ressave);
if (res == NULL) /* was not able to bind to any address */ if (res == NULL) /* was not able to bind to any address */
return -1; return -1;
@ -75,59 +77,65 @@ bind_socket(int sockfd, const char *addr)
* independent implementation (mostly for IPv4 and IPv6 addresses.) * independent implementation (mostly for IPv4 and IPv6 addresses.)
*/ */
int int
opensock(const char *host, int port, const char *bind_to) opensock (const char *host, int port, const char *bind_to)
{ {
int sockfd, n; int sockfd, n;
struct addrinfo hints, *res, *ressave; struct addrinfo hints, *res, *ressave;
char portstr[6]; char portstr[6];
assert(host != NULL); assert (host != NULL);
assert(port > 0); assert (port > 0);
memset(&hints, 0, sizeof(struct addrinfo)); memset (&hints, 0, sizeof (struct addrinfo));
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
snprintf(portstr, sizeof(portstr), "%d", port); snprintf (portstr, sizeof (portstr), "%d", port);
n = getaddrinfo(host, portstr, &hints, &res); n = getaddrinfo (host, portstr, &hints, &res);
if (n != 0) { if (n != 0)
log_message(LOG_ERR, "opensock: Could not retrieve info for %s", {
host); log_message (LOG_ERR, "opensock: Could not retrieve info for %s", host);
return -1; return -1;
} }
ressave = res; ressave = res;
do { do
sockfd = {
socket(res->ai_family, res->ai_socktype, res->ai_protocol); sockfd = socket (res->ai_family, res->ai_socktype, res->ai_protocol);
if (sockfd < 0) if (sockfd < 0)
continue; /* ignore this one */ continue; /* ignore this one */
/* Bind to the specified address */ /* Bind to the specified address */
if (bind_to) { if (bind_to)
if (bind_socket(sockfd, bind_to) < 0) { {
close(sockfd); if (bind_socket (sockfd, bind_to) < 0)
{
close (sockfd);
continue; /* can't bind, so try again */ continue; /* can't bind, so try again */
} }
} else if (config.bind_address) { }
if (bind_socket(sockfd, config.bind_address) < 0) { else if (config.bind_address)
close(sockfd); {
if (bind_socket (sockfd, config.bind_address) < 0)
{
close (sockfd);
continue; /* can't bind, so try again */ continue; /* can't bind, so try again */
} }
} }
if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0) if (connect (sockfd, res->ai_addr, res->ai_addrlen) == 0)
break; /* success */ break; /* success */
close(sockfd); close (sockfd);
} while ((res = res->ai_next) != NULL); }
while ((res = res->ai_next) != NULL);
freeaddrinfo(ressave); freeaddrinfo (ressave);
if (res == NULL) { if (res == NULL)
log_message(LOG_ERR, {
"opensock: Could not establish a connection to %s", log_message (LOG_ERR,
host); "opensock: Could not establish a connection to %s", host);
return -1; return -1;
} }
@ -138,28 +146,28 @@ opensock(const char *host, int port, const char *bind_to)
* Set the socket to non blocking -rjkaes * Set the socket to non blocking -rjkaes
*/ */
int 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); flags = fcntl (sock, F_GETFL, 0);
return fcntl(sock, F_SETFL, flags | O_NONBLOCK); return fcntl (sock, F_SETFL, flags | O_NONBLOCK);
} }
/* /*
* Set the socket to blocking -rjkaes * Set the socket to blocking -rjkaes
*/ */
int 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); flags = fcntl (sock, F_GETFL, 0);
return fcntl(sock, F_SETFL, flags & ~O_NONBLOCK); return fcntl (sock, F_SETFL, flags & ~O_NONBLOCK);
} }
/* /*
@ -169,43 +177,48 @@ socket_blocking(int sock)
* - rjkaes * - rjkaes
*/ */
int int
listen_sock(uint16_t port, socklen_t * addrlen) listen_sock (uint16_t port, socklen_t * addrlen)
{ {
int listenfd; int listenfd;
const int on = 1; const int on = 1;
struct sockaddr_in addr; struct sockaddr_in addr;
assert(port > 0); assert (port > 0);
assert(addrlen != NULL); assert (addrlen != NULL);
listenfd = socket(AF_INET, SOCK_STREAM, 0); listenfd = socket (AF_INET, SOCK_STREAM, 0);
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on));
memset(&addr, 0, sizeof(addr)); memset (&addr, 0, sizeof (addr));
addr.sin_family = AF_INET; addr.sin_family = AF_INET;
addr.sin_port = htons(port); addr.sin_port = htons (port);
if (config.ipAddr) { if (config.ipAddr)
addr.sin_addr.s_addr = inet_addr(config.ipAddr); {
} else { addr.sin_addr.s_addr = inet_addr (config.ipAddr);
addr.sin_addr.s_addr = inet_addr("0.0.0.0"); }
else
{
addr.sin_addr.s_addr = inet_addr ("0.0.0.0");
} }
if (bind(listenfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { if (bind (listenfd, (struct sockaddr *) &addr, sizeof (addr)) < 0)
log_message(LOG_ERR, {
log_message (LOG_ERR,
"Unable to bind listening socket because of %s", "Unable to bind listening socket because of %s",
strerror(errno)); strerror (errno));
return -1; return -1;
} }
if (listen(listenfd, MAXLISTEN) < 0) { if (listen (listenfd, MAXLISTEN) < 0)
log_message(LOG_ERR, {
log_message (LOG_ERR,
"Unable to start listening socket because of %s", "Unable to start listening socket because of %s",
strerror(errno)); strerror (errno));
return -1; return -1;
} }
*addrlen = sizeof(addr); *addrlen = sizeof (addr);
return listenfd; return listenfd;
} }
@ -214,20 +227,21 @@ listen_sock(uint16_t port, socklen_t * addrlen)
* Takes a socket descriptor and returns the socket's IP address. * Takes a socket descriptor and returns the socket's IP address.
*/ */
int int
getsock_ip(int fd, char *ipaddr) getsock_ip (int fd, char *ipaddr)
{ {
struct sockaddr_storage name; struct sockaddr_storage name;
socklen_t namelen = sizeof(name); socklen_t namelen = sizeof (name);
assert(fd >= 0); assert (fd >= 0);
if (getsockname(fd, (struct sockaddr *)&name, &namelen) != 0) { if (getsockname (fd, (struct sockaddr *) &name, &namelen) != 0)
log_message(LOG_ERR, "getsock_ip: getsockname() error: %s", {
strerror(errno)); log_message (LOG_ERR, "getsock_ip: getsockname() error: %s",
strerror (errno));
return -1; return -1;
} }
if (get_ip_string((struct sockaddr *)&name, ipaddr, IP_LENGTH) == NULL) if (get_ip_string ((struct sockaddr *) &name, ipaddr, IP_LENGTH) == NULL)
return -1; return -1;
return 0; return 0;
@ -237,27 +251,27 @@ getsock_ip(int fd, char *ipaddr)
* Return the peer's socket information. * Return the peer's socket information.
*/ */
int int
getpeer_information(int fd, char *ipaddr, char *string_addr) getpeer_information (int fd, char *ipaddr, char *string_addr)
{ {
struct sockaddr_storage sa; struct sockaddr_storage sa;
socklen_t salen = sizeof sa; socklen_t salen = sizeof sa;
assert(fd >= 0); assert (fd >= 0);
assert(ipaddr != NULL); assert (ipaddr != NULL);
assert(string_addr != NULL); assert (string_addr != NULL);
/* Set the strings to default values */ /* Set the strings to default values */
ipaddr[0] = '\0'; ipaddr[0] = '\0';
strlcpy(string_addr, "[unknown]", HOSTNAME_LENGTH); strlcpy (string_addr, "[unknown]", HOSTNAME_LENGTH);
/* Look up the IP address */ /* Look up the IP address */
if (getpeername(fd, (struct sockaddr *) &sa, &salen) != 0) if (getpeername (fd, (struct sockaddr *) &sa, &salen) != 0)
return -1; return -1;
if (get_ip_string((struct sockaddr *)&sa, ipaddr, IP_LENGTH) == NULL) if (get_ip_string ((struct sockaddr *) &sa, ipaddr, IP_LENGTH) == NULL)
return -1; return -1;
/* Get the full host name */ /* Get the full host name */
return getnameinfo((struct sockaddr *)&sa, salen, return getnameinfo ((struct sockaddr *) &sa, salen,
string_addr, HOSTNAME_LENGTH, NULL, 0, 0); string_addr, HOSTNAME_LENGTH, NULL, 0, 0);
} }

View File

@ -28,13 +28,13 @@
#define MAXLINE (1024 * 4) #define MAXLINE (1024 * 4)
extern int opensock(const char *host, int port, const char *bind_to); extern int opensock (const char *host, int port, const char *bind_to);
extern int listen_sock(uint16_t port, socklen_t * addrlen); extern int listen_sock (uint16_t port, socklen_t * addrlen);
extern int socket_nonblocking(int sock); extern int socket_nonblocking (int sock);
extern int socket_blocking(int sock); extern int socket_blocking (int sock);
extern int getsock_ip(int fd, char *ipaddr); extern int getsock_ip (int fd, char *ipaddr);
extern int getpeer_information(int fd, char *ipaddr, char *string_addr); extern int getpeer_information (int fd, char *ipaddr, char *string_addr);
#endif #endif

View File

@ -33,7 +33,8 @@
#include "stats.h" #include "stats.h"
#include "utils.h" #include "utils.h"
struct stat_s { struct stat_s
{
unsigned long int num_reqs; unsigned long int num_reqs;
unsigned long int num_badcons; unsigned long int num_badcons;
unsigned long int num_open; unsigned long int num_open;
@ -47,20 +48,20 @@ static struct stat_s *stats;
* Initialize the statistics information to zero. * Initialize the statistics information to zero.
*/ */
void void
init_stats(void) init_stats (void)
{ {
stats = malloc_shared_memory(sizeof(struct stat_s)); stats = malloc_shared_memory (sizeof (struct stat_s));
if (stats == MAP_FAILED) if (stats == MAP_FAILED)
return; return;
memset(stats, 0, sizeof(struct stat_s)); memset (stats, 0, sizeof (struct stat_s));
} }
/* /*
* Display the statics of the tinyproxy server. * Display the statics of the tinyproxy server.
*/ */
int int
showstats(struct conn_s *connptr) showstats (struct conn_s *connptr)
{ {
static char *msg = static char *msg =
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
@ -77,51 +78,50 @@ showstats(struct conn_s *connptr)
"Number of refused connections due to high load: %lu\n" "Number of refused connections due to high load: %lu\n"
"</p>\n" "</p>\n"
"<hr />\n" "<hr />\n"
"<p><em>Generated by %s version %s.</em></p>\n" "<p><em>Generated by %s version %s.</em></p>\n" "</body>\n" "</html>\n";
"</body>\n"
"</html>\n";
char *message_buffer; char *message_buffer;
char opens[16], reqs[16], badconns[16], denied[16], refused[16]; char opens[16], reqs[16], badconns[16], denied[16], refused[16];
FILE *statfile; FILE *statfile;
snprintf(opens, sizeof(opens), "%lu", stats->num_open); snprintf (opens, sizeof (opens), "%lu", stats->num_open);
snprintf(reqs, sizeof(reqs), "%lu", stats->num_reqs); snprintf (reqs, sizeof (reqs), "%lu", stats->num_reqs);
snprintf(badconns, sizeof(badconns), "%lu", stats->num_badcons); snprintf (badconns, sizeof (badconns), "%lu", stats->num_badcons);
snprintf(denied, sizeof(denied), "%lu", stats->num_denied); snprintf (denied, sizeof (denied), "%lu", stats->num_denied);
snprintf(refused, sizeof(refused), "%lu", stats->num_refused); snprintf (refused, sizeof (refused), "%lu", stats->num_refused);
if (!config.statpage || (!(statfile = fopen(config.statpage, "r")))) { if (!config.statpage || (!(statfile = fopen (config.statpage, "r"))))
message_buffer = safemalloc(MAXBUFFSIZE); {
message_buffer = safemalloc (MAXBUFFSIZE);
if (!message_buffer) if (!message_buffer)
return -1; return -1;
snprintf(message_buffer, MAXBUFFSIZE, msg, snprintf (message_buffer, MAXBUFFSIZE, msg,
PACKAGE, VERSION, PACKAGE, VERSION, PACKAGE, VERSION, PACKAGE, VERSION,
stats->num_open, stats->num_open,
stats->num_reqs, stats->num_reqs,
stats->num_badcons, stats->num_denied, stats->num_badcons, stats->num_denied,
stats->num_refused, stats->num_refused, PACKAGE, VERSION);
PACKAGE, VERSION);
if (send_http_message(connptr, 200, "OK", message_buffer) < 0) { if (send_http_message (connptr, 200, "OK", message_buffer) < 0)
safefree(message_buffer); {
safefree (message_buffer);
return -1; return -1;
} }
safefree(message_buffer); safefree (message_buffer);
return 0; return 0;
} }
add_error_variable(connptr, "opens", opens); add_error_variable (connptr, "opens", opens);
add_error_variable(connptr, "reqs", reqs); add_error_variable (connptr, "reqs", reqs);
add_error_variable(connptr, "badconns", badconns); add_error_variable (connptr, "badconns", badconns);
add_error_variable(connptr, "deniedconns", denied); add_error_variable (connptr, "deniedconns", denied);
add_error_variable(connptr, "refusedconns", refused); add_error_variable (connptr, "refusedconns", refused);
add_standard_vars(connptr); add_standard_vars (connptr);
send_http_headers(connptr, 200, "Statistic requested"); send_http_headers (connptr, 200, "Statistic requested");
send_html_file(statfile, connptr); send_html_file (statfile, connptr);
fclose(statfile); fclose (statfile);
return 0; return 0;
} }
@ -131,9 +131,10 @@ showstats(struct conn_s *connptr)
* stats.h * stats.h
*/ */
int int
update_stats(status_t update_level) update_stats (status_t update_level)
{ {
switch (update_level) { switch (update_level)
{
case STAT_BADCONN: case STAT_BADCONN:
++stats->num_badcons; ++stats->num_badcons;
break; break;

View File

@ -26,7 +26,8 @@
/* /*
* Various logable statistics * Various logable statistics
*/ */
typedef enum { typedef enum
{
STAT_BADCONN, /* bad connection, for unknown reason */ STAT_BADCONN, /* bad connection, for unknown reason */
STAT_OPEN, /* connection opened */ STAT_OPEN, /* connection opened */
STAT_CLOSE, /* connection closed */ STAT_CLOSE, /* connection closed */
@ -37,8 +38,8 @@ typedef enum {
/* /*
* Public API to the statistics for tinyproxy * Public API to the statistics for tinyproxy
*/ */
extern void init_stats(void); extern void init_stats (void);
extern int showstats(struct conn_s *connptr); extern int showstats (struct conn_s *connptr);
extern int update_stats(status_t update_level); extern int update_stats (status_t update_level);
#endif #endif

View File

@ -33,15 +33,15 @@
* destination buffer. * destination buffer.
*/ */
size_t 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 len = strlen (src);
size_t ret = len; size_t ret = len;
if (len >= size) if (len >= size)
len = size - 1; len = size - 1;
memcpy(dst, src, len); memcpy (dst, src, len);
dst[len] = '\0'; dst[len] = '\0';
return ret; return ret;
@ -56,16 +56,17 @@ strlcpy(char *dst, const char *src, size_t size)
* length. * length.
*/ */
size_t 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 len1 = strlen (dst);
size_t len2 = strlen(src); size_t len2 = strlen (src);
size_t ret = len1 + len2; size_t ret = len1 + len2;
if (len1 + len2 >= size) if (len1 + len2 >= size)
len2 = size - len1 - 1; len2 = size - len1 - 1;
if (len2 > 0) { if (len2 > 0)
memcpy(dst + len1, src, len2); {
memcpy (dst + len1, src, len2);
dst[len1 + len2] = '\0'; dst[len1 + len2] = '\0';
} }
@ -83,12 +84,12 @@ strlcat(char *dst, const char *src, size_t size)
* negative return value indicates an error. * negative return value indicates an error.
*/ */
ssize_t ssize_t
chomp(char *buffer, size_t length) chomp (char *buffer, size_t length)
{ {
size_t chars; size_t chars;
assert(buffer != NULL); assert (buffer != NULL);
assert(length > 0); assert (length > 0);
/* Make sure the arguments are valid */ /* Make sure the arguments are valid */
if (buffer == NULL) if (buffer == NULL)
@ -99,7 +100,8 @@ chomp(char *buffer, size_t length)
chars = 0; chars = 0;
--length; --length;
while (buffer[length] == '\r' || buffer[length] == '\n') { while (buffer[length] == '\r' || buffer[length] == '\n')
{
buffer[length] = '\0'; buffer[length] = '\0';
chars++; chars++;

View File

@ -22,13 +22,13 @@
#define TINYPROXY_TEXT_H #define TINYPROXY_TEXT_H
#ifndef HAVE_STRLCAT #ifndef HAVE_STRLCAT
extern size_t strlcat(char *dst, const char *src, size_t size); extern size_t strlcat (char *dst, const char *src, size_t size);
#endif /* HAVE_STRLCAT */ #endif /* HAVE_STRLCAT */
#ifndef HAVE_STRLCPY #ifndef HAVE_STRLCPY
extern size_t strlcpy(char *dst, const char *src, size_t size); extern size_t strlcpy (char *dst, const char *src, size_t size);
#endif /* HAVE_STRLCPY */ #endif /* HAVE_STRLCPY */
extern ssize_t chomp(char *buffer, size_t length); extern ssize_t chomp (char *buffer, size_t length);
#endif #endif

View File

@ -41,7 +41,7 @@
#include "stats.h" #include "stats.h"
#include "utils.h" #include "utils.h"
RETSIGTYPE takesig(int sig); RETSIGTYPE takesig (int sig);
/* /*
* Global Structures * Global Structures
@ -55,12 +55,13 @@ unsigned int processed_config_file = FALSE; /* boolean */
* Handle a signal * Handle a signal
*/ */
RETSIGTYPE RETSIGTYPE
takesig(int sig) takesig (int sig)
{ {
pid_t pid; pid_t pid;
int status; int status;
switch (sig) { switch (sig)
{
case SIGHUP: case SIGHUP:
received_sighup = TRUE; received_sighup = TRUE;
break; break;
@ -70,7 +71,7 @@ takesig(int sig)
break; break;
case SIGCHLD: case SIGCHLD:
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) ; while ((pid = waitpid (-1, &status, WNOHANG)) > 0);
break; break;
} }
@ -81,20 +82,20 @@ takesig(int sig)
* Display the version information for the user. * Display the version information for the user.
*/ */
static void 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. * Display the copyright and license for this program.
*/ */
static void static void
display_license(void) display_license (void)
{ {
display_version(); display_version ();
printf("\ printf ("\
Copyright 1998 Steven Young (sdyoung@well.com)\n\ Copyright 1998 Steven Young (sdyoung@well.com)\n\
Copyright 1998-2002 Robert James Kaes (rjkaes@users.sourceforge.net)\n\ Copyright 1998-2002 Robert James Kaes (rjkaes@users.sourceforge.net)\n\
Copyright 1999 George Talusan (gstalusan@uwaterloo.ca)\n\ Copyright 1999 George Talusan (gstalusan@uwaterloo.ca)\n\
@ -119,10 +120,10 @@ display_license(void)
* Display usage to the user. * Display usage to the user.
*/ */
static void static void
display_usage(void) display_usage (void)
{ {
printf("Usage: %s [options]\n", PACKAGE); printf ("Usage: %s [options]\n", PACKAGE);
printf("\ printf ("\
Options:\n\ Options:\n\
-d Operate in DEBUG mode.\n\ -d Operate in DEBUG mode.\n\
-c FILE Use an alternate configuration file.\n\ -c FILE Use an alternate configuration file.\n\
@ -131,21 +132,21 @@ Options:\n\
-v Display the version number.\n"); -v Display the version number.\n");
/* Display the modes compiled into tinyproxy */ /* Display the modes compiled into tinyproxy */
printf("\nFeatures compiled in:\n"); printf ("\nFeatures compiled in:\n");
#ifdef XTINYPROXY_ENABLE #ifdef XTINYPROXY_ENABLE
printf(" XTinyproxy header\n"); printf (" XTinyproxy header\n");
#endif /* XTINYPROXY */ #endif /* XTINYPROXY */
#ifdef FILTER_ENABLE #ifdef FILTER_ENABLE
printf(" Filtering\n"); printf (" Filtering\n");
#endif /* FILTER_ENABLE */ #endif /* FILTER_ENABLE */
#ifndef NDEBUG #ifndef NDEBUG
printf(" Debugging code\n"); printf (" Debugging code\n");
#endif /* NDEBUG */ #endif /* NDEBUG */
#ifdef TRANSPARENT_PROXY #ifdef TRANSPARENT_PROXY
printf(" Transparent proxy support\n"); printf (" Transparent proxy support\n");
#endif /* TRANSPARENT_PROXY */ #endif /* TRANSPARENT_PROXY */
#ifdef REVERSE_SUPPORT #ifdef REVERSE_SUPPORT
printf(" Reverse proxy support\n"); printf (" Reverse proxy support\n");
#endif /* REVERSE_SUPPORT */ #endif /* REVERSE_SUPPORT */
} }
@ -158,17 +159,18 @@ get_id (char *str)
return -1; return -1;
tstr = str; tstr = str;
while (*tstr != 0) { while (*tstr != 0)
if (!isdigit(*tstr)) {
if (!isdigit (*tstr))
return -1; return -1;
tstr++; tstr++;
} }
return atoi(str); return atoi (str);
} }
int int
main(int argc, char **argv) main (int argc, char **argv)
{ {
int optch; int optch;
unsigned int godaemon = TRUE; /* boolean */ unsigned int godaemon = TRUE; /* boolean */
@ -179,7 +181,7 @@ main(int argc, char **argv)
/* Only allow u+rw bits. This may be required for some versions /* Only allow u+rw bits. This may be required for some versions
* of glibc so that mkstemp() doesn't make us vulnerable. * of glibc so that mkstemp() doesn't make us vulnerable.
*/ */
umask(0177); umask (0177);
/* Default configuration file location */ /* Default configuration file location */
config.config_file = DEFAULT_CONF_FILE; config.config_file = DEFAULT_CONF_FILE;
@ -187,34 +189,35 @@ main(int argc, char **argv)
/* /*
* Process the various options * Process the various options
*/ */
while ((optch = getopt(argc, argv, "c:vldh")) != EOF) { while ((optch = getopt (argc, argv, "c:vldh")) != EOF)
switch (optch) { {
switch (optch)
{
case 'v': case 'v':
display_version(); display_version ();
exit(EX_OK); exit (EX_OK);
case 'l': case 'l':
display_license(); display_license ();
exit(EX_OK); exit (EX_OK);
case 'd': case 'd':
godaemon = FALSE; godaemon = FALSE;
break; break;
case 'c': case 'c':
config.config_file = safestrdup(optarg); config.config_file = safestrdup (optarg);
if (!config.config_file) { if (!config.config_file)
fprintf(stderr, {
"%s: Could not allocate memory.\n", fprintf (stderr, "%s: Could not allocate memory.\n", argv[0]);
argv[0]); exit (EX_SOFTWARE);
exit(EX_SOFTWARE);
} }
break; break;
case 'h': case 'h':
default: default:
display_usage(); display_usage ();
exit(EX_OK); exit (EX_OK);
} }
} }
log_message(LOG_INFO, "Initializing " PACKAGE " ..."); log_message (LOG_INFO, "Initializing " PACKAGE " ...");
/* /*
* Make sure the HTML error pages array is NULL to begin with. * Make sure the HTML error pages array is NULL to begin with.
@ -225,72 +228,82 @@ main(int argc, char **argv)
/* /*
* Read in the settings from the config file. * Read in the settings from the config file.
*/ */
config_file = fopen(config.config_file, "r"); config_file = fopen (config.config_file, "r");
if (!config_file) { if (!config_file)
fprintf(stderr, {
fprintf (stderr,
"%s: Could not open configuration file \"%s\".\n", "%s: Could not open configuration file \"%s\".\n",
argv[0], config.config_file); argv[0], config.config_file);
exit(EX_SOFTWARE); exit (EX_SOFTWARE);
} }
if (config_compile() || config_parse(&config, config_file)) { if (config_compile () || config_parse (&config, config_file))
fprintf(stderr, {
fprintf (stderr,
"Unable to parse configuration file. Not starting.\n"); "Unable to parse configuration file. Not starting.\n");
exit(EX_SOFTWARE); exit (EX_SOFTWARE);
} }
fclose(config_file); fclose (config_file);
/* /*
* Write to a user supplied log file if it's defined. This * Write to a user supplied log file if it's defined. This
* will override using the syslog even if syslog is defined. * will override using the syslog even if syslog is defined.
*/ */
if (config.logf_name) { if (config.logf_name)
if (open_log_file(config.logf_name) < 0) { {
fprintf(stderr, if (open_log_file (config.logf_name) < 0)
"%s: Could not create log file.\n", argv[0]); {
exit(EX_SOFTWARE); fprintf (stderr, "%s: Could not create log file.\n", argv[0]);
exit (EX_SOFTWARE);
} }
config.syslog = FALSE; /* disable syslog */ config.syslog = FALSE; /* disable syslog */
} else if (config.syslog) { }
else if (config.syslog)
{
if (godaemon == TRUE) if (godaemon == TRUE)
openlog("tinyproxy", LOG_PID, LOG_DAEMON); openlog ("tinyproxy", LOG_PID, LOG_DAEMON);
else else
openlog("tinyproxy", LOG_PID, LOG_USER); openlog ("tinyproxy", LOG_PID, LOG_USER);
} else { }
fprintf(stderr, else
{
fprintf (stderr,
"%s: Either define a logfile or enable syslog logging\n", "%s: Either define a logfile or enable syslog logging\n",
argv[0]); argv[0]);
exit(EX_SOFTWARE); exit (EX_SOFTWARE);
} }
processed_config_file = TRUE; processed_config_file = TRUE;
send_stored_logs(); send_stored_logs ();
/* /*
* Set the default values if they were not set in the config file. * Set the default values if they were not set in the config file.
*/ */
if (config.port == 0) { if (config.port == 0)
fprintf(stderr, {
fprintf (stderr,
"%s: You MUST set a Port in the configuration file.\n", "%s: You MUST set a Port in the configuration file.\n",
argv[0]); argv[0]);
exit(EX_SOFTWARE); exit (EX_SOFTWARE);
} }
if (!config.stathost) { if (!config.stathost)
log_message(LOG_INFO, "Setting stathost to \"%s\".", {
DEFAULT_STATHOST); log_message (LOG_INFO, "Setting stathost to \"%s\".", DEFAULT_STATHOST);
config.stathost = DEFAULT_STATHOST; config.stathost = DEFAULT_STATHOST;
} }
if (!config.user) { if (!config.user)
log_message(LOG_WARNING, {
log_message (LOG_WARNING,
"You SHOULD set a UserName in the configuration file. Using current user instead."); "You SHOULD set a UserName in the configuration file. Using current user instead.");
} }
if (config.idletimeout == 0) { if (config.idletimeout == 0)
log_message(LOG_WARNING, {
log_message (LOG_WARNING,
"Invalid idle time setting. Only values greater than zero allowed; therefore setting idle timeout to %u seconds.", "Invalid idle time setting. Only values greater than zero allowed; therefore setting idle timeout to %u seconds.",
MAX_IDLE_TIME); MAX_IDLE_TIME);
config.idletimeout = MAX_IDLE_TIME; config.idletimeout = MAX_IDLE_TIME;
} }
init_stats(); init_stats ();
/* /*
* If ANONYMOUS is turned on, make sure that Content-Length is * If ANONYMOUS is turned on, make sure that Content-Length is
@ -299,150 +312,163 @@ main(int argc, char **argv)
* hand in hand with Content-Length. * hand in hand with Content-Length.
* - rjkaes * - rjkaes
*/ */
if (is_anonymous_enabled()) { if (is_anonymous_enabled ())
anonymous_insert("Content-Length"); {
anonymous_insert("Content-Type"); anonymous_insert ("Content-Length");
anonymous_insert ("Content-Type");
} }
if (godaemon == TRUE) if (godaemon == TRUE)
makedaemon(); makedaemon ();
if (config.pidpath) { if (config.pidpath)
if (pidfile_create(config.pidpath) < 0) { {
fprintf(stderr, "%s: Could not create PID file.\n", if (pidfile_create (config.pidpath) < 0)
argv[0]); {
exit(EX_OSERR); fprintf (stderr, "%s: Could not create PID file.\n", argv[0]);
exit (EX_OSERR);
} }
} }
if (set_signal_handler(SIGPIPE, SIG_IGN) == SIG_ERR) { if (set_signal_handler (SIGPIPE, SIG_IGN) == SIG_ERR)
fprintf(stderr, "%s: Could not set the \"SIGPIPE\" signal.\n", {
fprintf (stderr, "%s: Could not set the \"SIGPIPE\" signal.\n",
argv[0]); argv[0]);
exit(EX_OSERR); exit (EX_OSERR);
} }
#ifdef FILTER_ENABLE #ifdef FILTER_ENABLE
if (config.filter) if (config.filter)
filter_init(); filter_init ();
#endif /* FILTER_ENABLE */ #endif /* FILTER_ENABLE */
/* /*
* Start listening on the selected port. * Start listening on the selected port.
*/ */
if (child_listening_sock(config.port) < 0) { if (child_listening_sock (config.port) < 0)
fprintf(stderr, "%s: Could not create listening socket.\n", {
argv[0]); fprintf (stderr, "%s: Could not create listening socket.\n", argv[0]);
exit(EX_OSERR); exit (EX_OSERR);
} }
/* /*
* Switch to a different user. * Switch to a different user.
*/ */
if (geteuid() == 0) { if (geteuid () == 0)
if (config.group && strlen(config.group) > 0) { {
int gid = get_id(config.group); if (config.group && strlen (config.group) > 0)
if (gid < 0) { {
thisgroup = getgrnam(config.group); int gid = get_id (config.group);
if (!thisgroup) { if (gid < 0)
fprintf(stderr, {
thisgroup = getgrnam (config.group);
if (!thisgroup)
{
fprintf (stderr,
"%s: Unable to find " "%s: Unable to find "
"group \"%s\".\n", "group \"%s\".\n", argv[0], config.group);
argv[0], config.group); exit (EX_NOUSER);
exit(EX_NOUSER);
} }
gid = thisgroup->gr_gid; gid = thisgroup->gr_gid;
} }
if (setgid(gid) < 0) { if (setgid (gid) < 0)
fprintf(stderr, {
fprintf (stderr,
"%s: Unable to change to " "%s: Unable to change to "
"group \"%s\".\n", "group \"%s\".\n", argv[0], config.group);
argv[0], config.group); exit (EX_CANTCREAT);
exit(EX_CANTCREAT);
} }
log_message(LOG_INFO, "Now running as group \"%s\".", log_message (LOG_INFO, "Now running as group \"%s\".",
config.group); config.group);
} }
if (config.user && strlen(config.user) > 0) { if (config.user && strlen (config.user) > 0)
int uid = get_id(config.user); {
if (uid < 0) { int uid = get_id (config.user);
thisuser = getpwnam(config.user); if (uid < 0)
if (!thisuser) { {
fprintf(stderr, thisuser = getpwnam (config.user);
if (!thisuser)
{
fprintf (stderr,
"%s: Unable to find " "%s: Unable to find "
"user \"%s\".", "user \"%s\".", argv[0], config.user);
argv[0], config.user); exit (EX_NOUSER);
exit(EX_NOUSER);
} }
uid = thisuser->pw_uid; uid = thisuser->pw_uid;
} }
if (setuid(uid) < 0) { if (setuid (uid) < 0)
fprintf(stderr, {
fprintf (stderr,
"%s: Unable to change to user \"%s\".", "%s: Unable to change to user \"%s\".",
argv[0], config.user); argv[0], config.user);
exit(EX_CANTCREAT); exit (EX_CANTCREAT);
} }
log_message(LOG_INFO, "Now running as user \"%s\".", log_message (LOG_INFO, "Now running as user \"%s\".", config.user);
config.user);
} }
} else { }
log_message(LOG_WARNING, else
{
log_message (LOG_WARNING,
"Not running as root, so not changing UID/GID."); "Not running as root, so not changing UID/GID.");
} }
if (child_pool_create() < 0) { if (child_pool_create () < 0)
fprintf(stderr, "%s: Could not create the pool of children.", {
argv[0]); fprintf (stderr, "%s: Could not create the pool of children.", argv[0]);
exit(EX_SOFTWARE); exit (EX_SOFTWARE);
} }
/* /*
* These signals are only for the parent process. * These signals are only for the parent process.
*/ */
log_message(LOG_INFO, "Setting the various signals."); log_message (LOG_INFO, "Setting the various signals.");
if (set_signal_handler(SIGCHLD, takesig) == SIG_ERR) { if (set_signal_handler (SIGCHLD, takesig) == SIG_ERR)
fprintf(stderr, "%s: Could not set the \"SIGCHLD\" signal.\n", {
fprintf (stderr, "%s: Could not set the \"SIGCHLD\" signal.\n",
argv[0]); argv[0]);
exit(EX_OSERR); exit (EX_OSERR);
} }
if (set_signal_handler(SIGTERM, takesig) == SIG_ERR) { if (set_signal_handler (SIGTERM, takesig) == SIG_ERR)
fprintf(stderr, "%s: Could not set the \"SIGTERM\" signal.\n", {
fprintf (stderr, "%s: Could not set the \"SIGTERM\" signal.\n",
argv[0]); argv[0]);
exit(EX_OSERR); exit (EX_OSERR);
} }
if (set_signal_handler(SIGHUP, takesig) == SIG_ERR) { if (set_signal_handler (SIGHUP, takesig) == SIG_ERR)
fprintf(stderr, "%s: Could not set the \"SIGHUP\" signal.\n", {
argv[0]); fprintf (stderr, "%s: Could not set the \"SIGHUP\" signal.\n", argv[0]);
exit(EX_OSERR); exit (EX_OSERR);
} }
/* /*
* Start the main loop. * Start the main loop.
*/ */
log_message(LOG_INFO, "Starting main loop. Accepting connections."); log_message (LOG_INFO, "Starting main loop. Accepting connections.");
child_main_loop(); child_main_loop ();
log_message(LOG_INFO, "Shutting down."); log_message (LOG_INFO, "Shutting down.");
child_kill_children(); child_kill_children ();
child_close_sock(); child_close_sock ();
/* /*
* Remove the PID file. * Remove the PID file.
*/ */
if (unlink(config.pidpath) < 0) { if (unlink (config.pidpath) < 0)
log_message(LOG_WARNING, {
log_message (LOG_WARNING,
"Could not remove PID file \"%s\": %s.", "Could not remove PID file \"%s\": %s.",
config.pidpath, strerror(errno)); config.pidpath, strerror (errno));
} }
#ifdef FILTER_ENABLE #ifdef FILTER_ENABLE
if (config.filter) if (config.filter)
filter_destroy(); filter_destroy ();
#endif /* FILTER_ENABLE */ #endif /* FILTER_ENABLE */
if (config.syslog) if (config.syslog)
closelog(); closelog ();
else else
close_log_file(); close_log_file ();
exit(EX_OK); exit (EX_OK);
} }

View File

@ -33,7 +33,8 @@
* Even if upstream support is not compiled into tinyproxy, this * Even if upstream support is not compiled into tinyproxy, this
* structure still needs to be defined. * structure still needs to be defined.
*/ */
struct upstream { struct upstream
{
struct upstream *next; struct upstream *next;
char *domain; /* optional */ char *domain; /* optional */
char *host; char *host;
@ -44,7 +45,8 @@ struct upstream {
/* /*
* Hold all the configuration time information. * Hold all the configuration time information.
*/ */
struct config_s { struct config_s
{
char *logf_name; char *logf_name;
char *config_file; char *config_file;
unsigned int syslog; /* boolean */ unsigned int syslog; /* boolean */

View File

@ -36,81 +36,81 @@
* Build a URL from parts. * Build a URL from parts.
*/ */
static int 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 (url != NULL);
assert(host != NULL); assert (host != NULL);
assert(port > 0 && port < 32768); assert (port > 0 && port < 32768);
assert(path != NULL); assert (path != NULL);
len = strlen(host) + strlen(path) + 14; len = strlen (host) + strlen (path) + 14;
*url = safemalloc(len); *url = safemalloc (len);
if (*url == NULL) if (*url == NULL)
return -1; 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 int
do_transparent_proxy(struct conn_s *connptr, hashmap_t hashofheaders, do_transparent_proxy (struct conn_s *connptr, hashmap_t hashofheaders,
struct request_s *request, struct config_s *conf, char *url) struct request_s *request, struct config_s *conf,
char *url)
{ {
socklen_t length; socklen_t length;
char *data; char *data;
length = length = hashmap_entry_by_key (hashofheaders, "host", (void **) &data);
hashmap_entry_by_key(hashofheaders, "host", (void **)&data); if (length <= 0)
if (length <= 0) { {
struct sockaddr_in dest_addr; struct sockaddr_in dest_addr;
if (getsockname if (getsockname
(connptr->client_fd, (struct sockaddr *)&dest_addr, (connptr->client_fd, (struct sockaddr *) &dest_addr, &length) < 0)
&length) < 0) { {
log_message(LOG_ERR, log_message (LOG_ERR,
"process_request: cannot get destination IP for %d", "process_request: cannot get destination IP for %d",
connptr->client_fd); connptr->client_fd);
indicate_http_error(connptr, 400, "Bad Request", indicate_http_error (connptr, 400, "Bad Request",
"detail", "detail",
"Unknown destination", "Unknown destination", "url", url, NULL);
"url", url, NULL);
return 0; return 0;
} }
request->host = safemalloc(17); request->host = safemalloc (17);
strcpy(request->host, inet_ntoa(dest_addr.sin_addr)); strcpy (request->host, inet_ntoa (dest_addr.sin_addr));
request->port = ntohs(dest_addr.sin_port); request->port = ntohs (dest_addr.sin_port);
request->path = safemalloc(strlen(url) + 1); request->path = safemalloc (strlen (url) + 1);
strcpy(request->path, url); strcpy (request->path, url);
safefree(url); safefree (url);
build_url(&url, request->host, request->port, build_url (&url, request->host, request->port, request->path);
request->path); log_message (LOG_INFO,
log_message(LOG_INFO,
"process_request: trans IP %s %s for %d", "process_request: trans IP %s %s for %d",
request->method, url, connptr->client_fd); request->method, url, connptr->client_fd);
} else { }
request->host = safemalloc(length + 1); else
if (sscanf {
(data, "%[^:]:%hu", request->host, request->host = safemalloc (length + 1);
&request->port) != 2) { if (sscanf (data, "%[^:]:%hu", request->host, &request->port) != 2)
strcpy(request->host, data); {
strcpy (request->host, data);
request->port = HTTP_PORT; request->port = HTTP_PORT;
} }
request->path = safemalloc(strlen(url) + 1); request->path = safemalloc (strlen (url) + 1);
strcpy(request->path, url); strcpy (request->path, url);
safefree(url); safefree (url);
build_url(&url, request->host, request->port, build_url (&url, request->host, request->port, request->path);
request->path); log_message (LOG_INFO,
log_message(LOG_INFO,
"process_request: trans Host %s %s for %d", "process_request: trans Host %s %s for %d",
request->method, url, connptr->client_fd); request->method, url, connptr->client_fd);
} }
if (conf->ipAddr && strcmp(request->host, conf->ipAddr) == 0) { if (conf->ipAddr && strcmp (request->host, conf->ipAddr) == 0)
log_message(LOG_ERR, {
log_message (LOG_ERR,
"process_request: destination IP is localhost %d", "process_request: destination IP is localhost %d",
connptr->client_fd); connptr->client_fd);
indicate_http_error(connptr, 400, "Bad Request", indicate_http_error (connptr, 400, "Bad Request",
"detail", "detail",
"You tried to connect to the machine the proxy is running on", "You tried to connect to the machine the proxy is running on",
"url", url, NULL); "url", url, NULL);

View File

@ -29,8 +29,9 @@
#include "hashmap.h" #include "hashmap.h"
#include "reqs.h" #include "reqs.h"
extern int do_transparent_proxy(struct conn_s *connptr, extern int do_transparent_proxy (struct conn_s *connptr,
hashmap_t hashofheaders, struct request_s *request, hashmap_t hashofheaders,
struct request_s *request,
struct config_s *config, char *url); struct config_s *config, char *url);

View File

@ -34,7 +34,7 @@
* Build the data for a complete HTTP & HTML message for the client. * Build the data for a complete HTTP & HTML message for the client.
*/ */
int int
send_http_message(struct conn_s *connptr, int http_code, send_http_message (struct conn_s *connptr, int http_code,
const char *error_title, const char *message) const char *error_title, const char *message)
{ {
static char *headers[] = { static char *headers[] = {
@ -45,14 +45,14 @@ send_http_message(struct conn_s *connptr, int http_code,
http_message_t msg; http_message_t msg;
msg = http_message_create(http_code, error_title); msg = http_message_create (http_code, error_title);
if (msg == NULL) if (msg == NULL)
return -1; return -1;
http_message_add_headers(msg, headers, 3); http_message_add_headers (msg, headers, 3);
http_message_set_body(msg, message, strlen(message)); http_message_set_body (msg, message, strlen (message));
http_message_send(msg, connptr->client_fd); http_message_send (msg, connptr->client_fd);
http_message_destroy(msg); http_message_destroy (msg);
return 0; return 0;
} }
@ -61,7 +61,7 @@ send_http_message(struct conn_s *connptr, int http_code,
* Safely creates filename and returns the low-level file descriptor. * Safely creates filename and returns the low-level file descriptor.
*/ */
int int
create_file_safely(const char *filename, unsigned int truncate_file) create_file_safely (const char *filename, unsigned int truncate_file)
{ {
struct stat lstatinfo; struct stat lstatinfo;
int fildes; int fildes;
@ -71,15 +71,17 @@ create_file_safely(const char *filename, unsigned int truncate_file)
* If it does exist, open it for writing and perform the fstat() * If it does exist, open it for writing and perform the fstat()
* check. * check.
*/ */
if (lstat(filename, &lstatinfo) < 0) { if (lstat (filename, &lstatinfo) < 0)
{
/* /*
* If lstat() failed for any reason other than "file not * If lstat() failed for any reason other than "file not
* existing", exit. * existing", exit.
*/ */
if (errno != ENOENT) { if (errno != ENOENT)
fprintf(stderr, {
fprintf (stderr,
"%s: Error checking file %s: %s\n", "%s: Error checking file %s: %s\n",
PACKAGE, filename, strerror(errno)); PACKAGE, filename, strerror (errno));
return -EACCES; return -EACCES;
} }
@ -88,14 +90,16 @@ create_file_safely(const char *filename, unsigned int truncate_file)
* sure an attacker can't slip in a file between the lstat() * sure an attacker can't slip in a file between the lstat()
* and open() * and open()
*/ */
if ((fildes = if ((fildes = open (filename, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0)
open(filename, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0) { {
fprintf(stderr, fprintf (stderr,
"%s: Could not create file %s: %s\n", "%s: Could not create file %s: %s\n",
PACKAGE, filename, strerror(errno)); PACKAGE, filename, strerror (errno));
return fildes; return fildes;
} }
} else { }
else
{
struct stat fstatinfo; struct stat fstatinfo;
int flags; int flags;
@ -106,10 +110,11 @@ create_file_safely(const char *filename, unsigned int truncate_file)
/* /*
* Open an existing file. * Open an existing file.
*/ */
if ((fildes = open(filename, flags)) < 0) { if ((fildes = open (filename, flags)) < 0)
fprintf(stderr, {
fprintf (stderr,
"%s: Could not open file %s: %s\n", "%s: Could not open file %s: %s\n",
PACKAGE, filename, strerror(errno)); PACKAGE, filename, strerror (errno));
return fildes; return fildes;
} }
@ -117,14 +122,15 @@ create_file_safely(const char *filename, unsigned int truncate_file)
* fstat() the opened file and check that the file mode bits, * fstat() the opened file and check that the file mode bits,
* inode, and device match. * inode, and device match.
*/ */
if (fstat(fildes, &fstatinfo) < 0 if (fstat (fildes, &fstatinfo) < 0
|| lstatinfo.st_mode != fstatinfo.st_mode || lstatinfo.st_mode != fstatinfo.st_mode
|| lstatinfo.st_ino != fstatinfo.st_ino || lstatinfo.st_ino != fstatinfo.st_ino
|| lstatinfo.st_dev != fstatinfo.st_dev) { || lstatinfo.st_dev != fstatinfo.st_dev)
fprintf(stderr, {
fprintf (stderr,
"%s: The file %s has been changed before it could be opened\n", "%s: The file %s has been changed before it could be opened\n",
PACKAGE, filename); PACKAGE, filename);
close(fildes); close (fildes);
return -EIO; return -EIO;
} }
@ -135,11 +141,12 @@ create_file_safely(const char *filename, unsigned int truncate_file)
* isn't strictly necessary because the fstat() vs lstat() * isn't strictly necessary because the fstat() vs lstat()
* st_mode check would also find this) * st_mode check would also find this)
*/ */
if (fstatinfo.st_nlink > 1 || !S_ISREG(lstatinfo.st_mode)) { if (fstatinfo.st_nlink > 1 || !S_ISREG (lstatinfo.st_mode))
fprintf(stderr, {
fprintf (stderr,
"%s: The file %s has too many links, or is not a regular file: %s\n", "%s: The file %s has too many links, or is not a regular file: %s\n",
PACKAGE, filename, strerror(errno)); PACKAGE, filename, strerror (errno));
close(fildes); close (fildes);
return -EMLINK; return -EMLINK;
} }
@ -159,14 +166,14 @@ create_file_safely(const char *filename, unsigned int truncate_file)
* ("Little sympathy has been extended") * ("Little sympathy has been extended")
*/ */
#ifdef HAVE_FTRUNCATE #ifdef HAVE_FTRUNCATE
ftruncate(fildes, 0); ftruncate (fildes, 0);
#else #else
close(fildes); close (fildes);
if ((fildes = if ((fildes = open (filename, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0)
open(filename, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) { {
fprintf(stderr, fprintf (stderr,
"%s: Could not open file %s: %s.", "%s: Could not open file %s: %s.",
PACKAGE, filename, strerror(errno)); PACKAGE, filename, strerror (errno));
return fildes; return fildes;
} }
#endif /* HAVE_FTRUNCATE */ #endif /* HAVE_FTRUNCATE */
@ -179,7 +186,7 @@ create_file_safely(const char *filename, unsigned int truncate_file)
* Write the PID of the program to the specified file. * Write the PID of the program to the specified file.
*/ */
int int
pidfile_create(const char *filename) pidfile_create (const char *filename)
{ {
int fildes; int fildes;
FILE *fd; FILE *fd;
@ -187,22 +194,23 @@ pidfile_create(const char *filename)
/* /*
* Create a new file * Create a new file
*/ */
if ((fildes = create_file_safely(filename, TRUE)) < 0) if ((fildes = create_file_safely (filename, TRUE)) < 0)
return fildes; return fildes;
/* /*
* Open a stdio file over the low-level one. * Open a stdio file over the low-level one.
*/ */
if ((fd = fdopen(fildes, "w")) == NULL) { if ((fd = fdopen (fildes, "w")) == NULL)
fprintf(stderr, {
fprintf (stderr,
"%s: Could not write PID file %s: %s.", "%s: Could not write PID file %s: %s.",
PACKAGE, filename, strerror(errno)); PACKAGE, filename, strerror (errno));
close(fildes); close (fildes);
unlink(filename); unlink (filename);
return -EIO; return -EIO;
} }
fprintf(fd, "%ld\n", (long)getpid()); fprintf (fd, "%ld\n", (long) getpid ());
fclose(fd); fclose (fd);
return 0; return 0;
} }

View File

@ -27,10 +27,11 @@
*/ */
struct conn_s; struct conn_s;
extern int send_http_message(struct conn_s *connptr, int http_code, extern int send_http_message (struct conn_s *connptr, int http_code,
const char *error_title, const char *message); const char *error_title, const char *message);
extern int pidfile_create(const char *path); extern int pidfile_create (const char *path);
extern int create_file_safely(const char *filename, unsigned int truncate_file); extern int create_file_safely (const char *filename,
unsigned int truncate_file);
#endif #endif

View File

@ -33,14 +33,16 @@
* vector_s stores a pointer to the first vector (vector[0]) and a * 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.) * count of the number of entries (or how long the vector is.)
*/ */
struct vectorentry_s { struct vectorentry_s
{
void *data; void *data;
size_t len; size_t len;
struct vectorentry_s *next; struct vectorentry_s *next;
}; };
struct vector_s { struct vector_s
{
size_t num_entries; size_t num_entries;
struct vectorentry_s *head; struct vectorentry_s *head;
struct vectorentry_s *tail; struct vectorentry_s *tail;
@ -54,11 +56,11 @@ struct vector_s {
* vector. * vector.
*/ */
vector_t vector_t
vector_create(void) vector_create (void)
{ {
vector_t vector; vector_t vector;
vector = safemalloc(sizeof(struct vector_s)); vector = safemalloc (sizeof (struct vector_s));
if (!vector) if (!vector)
return NULL; return NULL;
@ -75,7 +77,7 @@ vector_create(void)
* negative if a NULL vector is supplied * negative if a NULL vector is supplied
*/ */
int int
vector_delete(vector_t vector) vector_delete (vector_t vector)
{ {
struct vectorentry_s *ptr, *next; struct vectorentry_s *ptr, *next;
@ -83,15 +85,16 @@ vector_delete(vector_t vector)
return -EINVAL; return -EINVAL;
ptr = vector->head; ptr = vector->head;
while (ptr) { while (ptr)
{
next = ptr->next; next = ptr->next;
safefree(ptr->data); safefree (ptr->data);
safefree(ptr); safefree (ptr);
ptr = next; ptr = next;
} }
safefree(vector); safefree (vector);
return 0; return 0;
} }
@ -110,7 +113,7 @@ vector_delete(vector_t vector)
#define INSERT_APPEND 1 #define INSERT_APPEND 1
static int 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; struct vectorentry_s *entry;
@ -118,28 +121,32 @@ vector_insert(vector_t vector, void *data, ssize_t len, int pos)
(pos != INSERT_PREPEND && pos != INSERT_APPEND)) (pos != INSERT_PREPEND && pos != INSERT_APPEND))
return -EINVAL; return -EINVAL;
entry = safemalloc(sizeof(struct vectorentry_s)); entry = safemalloc (sizeof (struct vectorentry_s));
if (!entry) if (!entry)
return -ENOMEM; return -ENOMEM;
entry->data = safemalloc(len); entry->data = safemalloc (len);
if (!entry->data) { if (!entry->data)
safefree(entry); {
safefree (entry);
return -ENOMEM; return -ENOMEM;
} }
memcpy(entry->data, data, len); memcpy (entry->data, data, len);
entry->len = len; entry->len = len;
entry->next = NULL; entry->next = NULL;
/* If there is no head or tail, create them */ /* If there is no head or tail, create them */
if (!vector->head && !vector->tail) if (!vector->head && !vector->tail)
vector->head = vector->tail = entry; vector->head = vector->tail = entry;
else if (pos == 0) { else if (pos == 0)
{
/* prepend the entry */ /* prepend the entry */
entry->next = vector->head; entry->next = vector->head;
vector->head = entry; vector->head = entry;
} else { }
else
{
/* append the entry */ /* append the entry */
vector->tail->next = entry; vector->tail->next = entry;
vector->tail = entry; vector->tail = entry;
@ -156,15 +163,15 @@ vector_insert(vector_t vector, void *data, ssize_t len, int pos)
* arguments. * arguments.
*/ */
int 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 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,7 +182,7 @@ vector_prepend(vector_t vector, void *data, ssize_t len)
* length of data if position is valid * length of data if position is valid
*/ */
void * 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; struct vectorentry_s *ptr;
size_t loc; size_t loc;
@ -186,7 +193,8 @@ vector_getentry(vector_t vector, size_t pos, size_t * size)
loc = 0; loc = 0;
ptr = vector->head; ptr = vector->head;
while (loc != pos) { while (loc != pos)
{
ptr = ptr->next; ptr = ptr->next;
loc++; loc++;
} }
@ -204,7 +212,7 @@ vector_getentry(vector_t vector, size_t pos, size_t * size)
* positive length of vector otherwise * positive length of vector otherwise
*/ */
ssize_t ssize_t
vector_length(vector_t vector) vector_length (vector_t vector)
{ {
if (!vector) if (!vector)
return -EINVAL; return -EINVAL;

View File

@ -23,7 +23,8 @@
/* Allow the use in C++ code. */ /* Allow the use in C++ code. */
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C"
{
#endif #endif
/* /*
@ -37,8 +38,8 @@ extern "C" {
* vector_create() takes no arguments. * vector_create() takes no arguments.
* vector_delete() is self explanatory. * vector_delete() is self explanatory.
*/ */
extern vector_t vector_create(void); extern vector_t vector_create (void);
extern int vector_delete(vector_t vector); extern int vector_delete (vector_t vector);
/* /*
* When you insert a piece of data into the vector, the data will be * When you insert a piece of data into the vector, the data will be
@ -48,8 +49,8 @@ extern "C" {
* Returns: negative on error * Returns: negative on error
* 0 upon successful insert. * 0 upon successful insert.
*/ */
extern int vector_append(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); 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 * A pointer to the data at position "pos" (zero based) is returned and the
@ -67,8 +68,7 @@ extern "C" {
* Returns: NULL on error * Returns: NULL on error
* valid pointer to data * valid pointer to data
*/ */
extern void *vector_getentry(vector_t vector, size_t pos, extern void *vector_getentry (vector_t vector, size_t pos, size_t * size);
size_t * size);
/* /*
* Returns the number of enteries (or the length) of the vector. * Returns the number of enteries (or the length) of the vector.
@ -76,7 +76,7 @@ extern "C" {
* Returns: negative if vector is not valid * Returns: negative if vector is not valid
* positive length of vector otherwise * positive length of vector otherwise
*/ */
extern ssize_t vector_length(vector_t vector); extern ssize_t vector_length (vector_t vector);
#if defined(__cplusplus) #if defined(__cplusplus)
} }