Indent code to Tinyproxy coding style
The modified files were indented with GNU indent using the following command: indent -npro -kr -i8 -ts8 -sob -l80 -ss -cs -cp1 -bs -nlps -nprs -pcs \ -saf -sai -saw -sc -cdw -ce -nut -il0 No other changes of any sort were made.
This commit is contained in:
parent
2cb6777592
commit
7b9234f394
92
src/acl.c
92
src/acl.c
@ -33,8 +33,7 @@
|
||||
/* Define how long an IPv6 address is in bytes (128 bits, 16 bytes) */
|
||||
#define IPV6_LEN 16
|
||||
|
||||
enum acl_type
|
||||
{
|
||||
enum acl_type {
|
||||
ACL_STRING,
|
||||
ACL_NUMERIC,
|
||||
};
|
||||
@ -44,15 +43,12 @@ enum acl_type
|
||||
* whether it's an ALLOW or DENY entry, and also whether it's a string
|
||||
* entry (like a domain name) or an IP entry.
|
||||
*/
|
||||
struct acl_s
|
||||
{
|
||||
struct acl_s {
|
||||
acl_access_t access;
|
||||
enum acl_type type;
|
||||
union
|
||||
{
|
||||
union {
|
||||
char *string;
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
unsigned char octet[IPV6_LEN];
|
||||
unsigned char mask[IPV6_LEN];
|
||||
} ip;
|
||||
@ -64,7 +60,6 @@ struct acl_s
|
||||
*/
|
||||
static vector_t access_list = NULL;
|
||||
|
||||
|
||||
/*
|
||||
* Fills in the netmask array given a numeric value.
|
||||
*
|
||||
@ -94,20 +89,14 @@ fill_netmask_array (char *bitmask_string, unsigned char array[],
|
||||
return -1;
|
||||
|
||||
/* we have a valid range to fill in the array */
|
||||
for (i = 0; i != len; ++i)
|
||||
{
|
||||
if (mask >= 8)
|
||||
{
|
||||
for (i = 0; i != len; ++i) {
|
||||
if (mask >= 8) {
|
||||
array[i] = 0xff;
|
||||
mask -= 8;
|
||||
}
|
||||
else if (mask > 0)
|
||||
{
|
||||
} else if (mask > 0) {
|
||||
array[i] = (unsigned char) (0xff << (8 - mask));
|
||||
mask = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
array[i] = 0;
|
||||
}
|
||||
}
|
||||
@ -115,7 +104,6 @@ fill_netmask_array (char *bitmask_string, unsigned char array[],
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Inserts a new access control into the list. The function will figure out
|
||||
* whether the location is an IP address (with optional netmask) or a
|
||||
@ -125,8 +113,7 @@ fill_netmask_array (char *bitmask_string, unsigned char array[],
|
||||
* -1 on failure
|
||||
* 0 otherwise.
|
||||
*/
|
||||
int
|
||||
insert_acl (char *location, acl_access_t access_type)
|
||||
int insert_acl (char *location, acl_access_t access_type)
|
||||
{
|
||||
struct acl_s acl;
|
||||
int ret;
|
||||
@ -137,12 +124,11 @@ insert_acl (char *location, acl_access_t access_type)
|
||||
/*
|
||||
* If the access list has not been set up, create it.
|
||||
*/
|
||||
if (!access_list)
|
||||
{
|
||||
if (!access_list) {
|
||||
access_list = vector_create ();
|
||||
if (!access_list)
|
||||
{
|
||||
log_message (LOG_ERR, "Unable to allocate memory for access list");
|
||||
if (!access_list) {
|
||||
log_message (LOG_ERR,
|
||||
"Unable to allocate memory for access list");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -156,21 +142,17 @@ insert_acl (char *location, acl_access_t access_type)
|
||||
/*
|
||||
* 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;
|
||||
memcpy (acl.address.ip.octet, ip_dst, IPV6_LEN);
|
||||
memset (acl.address.ip.mask, 0xff, IPV6_LEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/*
|
||||
* At this point we're either a hostname or an
|
||||
* IP address with a slash.
|
||||
*/
|
||||
p = strchr (location, '/');
|
||||
if (p != NULL)
|
||||
{
|
||||
if (p != NULL) {
|
||||
/*
|
||||
* We have a slash, so it's intended to be an
|
||||
* IP address with mask
|
||||
@ -182,12 +164,11 @@ insert_acl (char *location, acl_access_t access_type)
|
||||
acl.type = ACL_NUMERIC;
|
||||
memcpy (acl.address.ip.octet, ip_dst, IPV6_LEN);
|
||||
|
||||
if (fill_netmask_array (p + 1, &(acl.address.ip.mask[0]), IPV6_LEN)
|
||||
if (fill_netmask_array
|
||||
(p + 1, &(acl.address.ip.mask[0]), IPV6_LEN)
|
||||
< 0)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* In all likelihood a string */
|
||||
acl.type = ACL_STRING;
|
||||
acl.address.string = safestrdup (location);
|
||||
@ -231,8 +212,7 @@ acl_string_processing (struct acl_s *acl,
|
||||
* do a string based test only; otherwise, we can do a reverse
|
||||
* lookup test as well.
|
||||
*/
|
||||
if (acl->address.string[0] != '.')
|
||||
{
|
||||
if (acl->address.string[0] != '.') {
|
||||
memset (&hints, 0, sizeof (struct addrinfo));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
@ -242,21 +222,17 @@ acl_string_processing (struct acl_s *acl,
|
||||
ressave = res;
|
||||
|
||||
match = FALSE;
|
||||
do
|
||||
{
|
||||
do {
|
||||
get_ip_string (res->ai_addr, ipbuf, sizeof (ipbuf));
|
||||
if (strcmp (ip_address, ipbuf) == 0)
|
||||
{
|
||||
if (strcmp (ip_address, ipbuf) == 0) {
|
||||
match = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while ((res = res->ai_next) != NULL);
|
||||
} while ((res = res->ai_next) != NULL);
|
||||
|
||||
freeaddrinfo (ressave);
|
||||
|
||||
if (match)
|
||||
{
|
||||
if (match) {
|
||||
if (acl->access == ACL_DENY)
|
||||
return 0;
|
||||
else
|
||||
@ -277,8 +253,7 @@ STRING_TEST:
|
||||
|
||||
if (strcasecmp
|
||||
(string_address + (test_length - match_length),
|
||||
acl->address.string) == 0)
|
||||
{
|
||||
acl->address.string) == 0) {
|
||||
if (acl->access == ACL_DENY)
|
||||
return 0;
|
||||
else
|
||||
@ -297,8 +272,7 @@ STRING_TEST:
|
||||
* 0 IP address is denied
|
||||
* -1 neither allowed nor denied.
|
||||
*/
|
||||
static int
|
||||
check_numeric_acl (const struct acl_s *acl, const char *ip)
|
||||
static int check_numeric_acl (const struct acl_s *acl, const char *ip)
|
||||
{
|
||||
uint8_t addr[IPV6_LEN], x, y;
|
||||
int i;
|
||||
@ -309,8 +283,7 @@ check_numeric_acl (const struct acl_s *acl, const char *ip)
|
||||
if (full_inet_pton (ip, &addr) <= 0)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i != IPV6_LEN; ++i)
|
||||
{
|
||||
for (i = 0; i != IPV6_LEN; ++i) {
|
||||
x = addr[i] & acl->address.ip.mask[i];
|
||||
y = acl->address.ip.octet[i] & acl->address.ip.mask[i];
|
||||
|
||||
@ -330,8 +303,7 @@ check_numeric_acl (const struct acl_s *acl, const char *ip)
|
||||
* 1 if allowed
|
||||
* 0 if denied
|
||||
*/
|
||||
int
|
||||
check_acl (const char *ip, const char *host)
|
||||
int check_acl (const char *ip, const char *host)
|
||||
{
|
||||
struct acl_s *acl;
|
||||
int perm = 0;
|
||||
@ -346,11 +318,9 @@ check_acl (const char *ip, const char *host)
|
||||
if (!access_list)
|
||||
return 1;
|
||||
|
||||
for (i = 0; i != (size_t)vector_length (access_list); ++i)
|
||||
{
|
||||
acl = (struct acl_s *)vector_getentry (access_list, i, NULL);
|
||||
switch (acl->type)
|
||||
{
|
||||
for (i = 0; i != (size_t) vector_length (access_list); ++i) {
|
||||
acl = (struct acl_s *) vector_getentry (access_list, i, NULL);
|
||||
switch (acl->type) {
|
||||
case ACL_STRING:
|
||||
perm = acl_string_processing (acl, ip, host);
|
||||
break;
|
||||
|
@ -21,8 +21,7 @@
|
||||
#ifndef TINYPROXY_ACL_H
|
||||
#define TINYPROXY_ACL_H
|
||||
|
||||
typedef enum
|
||||
{ ACL_ALLOW, ACL_DENY } acl_access_t;
|
||||
typedef enum { ACL_ALLOW, ACL_DENY } acl_access_t;
|
||||
|
||||
extern int insert_acl (char *location, acl_access_t access_type);
|
||||
extern int check_acl (const char *ip_address, const char *string_address);
|
||||
|
@ -29,8 +29,7 @@
|
||||
|
||||
static hashmap_t anonymous_map = NULL;
|
||||
|
||||
short int
|
||||
is_anonymous_enabled (void)
|
||||
short int is_anonymous_enabled (void)
|
||||
{
|
||||
return (anonymous_map != NULL) ? 1 : 0;
|
||||
}
|
||||
@ -39,8 +38,7 @@ is_anonymous_enabled (void)
|
||||
* Search for the header. This function returns a positive value greater than
|
||||
* zero if the string was found, zero if it wasn't and negative upon error.
|
||||
*/
|
||||
int
|
||||
anonymous_search (const char *s)
|
||||
int anonymous_search (const char *s)
|
||||
{
|
||||
assert (s != NULL);
|
||||
assert (anonymous_map != NULL);
|
||||
@ -54,22 +52,19 @@ anonymous_search (const char *s)
|
||||
* Return -1 if there is an error, otherwise a 0 is returned if the insert was
|
||||
* successful.
|
||||
*/
|
||||
int
|
||||
anonymous_insert (const char *s)
|
||||
int anonymous_insert (const char *s)
|
||||
{
|
||||
char data = 1;
|
||||
|
||||
assert (s != NULL);
|
||||
|
||||
if (!anonymous_map)
|
||||
{
|
||||
if (!anonymous_map) {
|
||||
anonymous_map = hashmap_create (32);
|
||||
if (!anonymous_map)
|
||||
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. */
|
||||
return 0;
|
||||
}
|
||||
|
89
src/buffer.c
89
src/buffer.c
@ -34,8 +34,7 @@
|
||||
#define BUFFER_HEAD(x) (x)->head
|
||||
#define BUFFER_TAIL(x) (x)->tail
|
||||
|
||||
struct bufline_s
|
||||
{
|
||||
struct bufline_s {
|
||||
unsigned char *string; /* the actual string of data */
|
||||
struct bufline_s *next; /* pointer to next in linked list */
|
||||
size_t length; /* length of the string of data */
|
||||
@ -46,8 +45,7 @@ struct bufline_s
|
||||
* The buffer structure points to the beginning and end of the buffer list
|
||||
* (and includes the total size)
|
||||
*/
|
||||
struct buffer_s
|
||||
{
|
||||
struct buffer_s {
|
||||
struct bufline_s *head; /* top of the buffer */
|
||||
struct bufline_s *tail; /* bottom of the buffer */
|
||||
size_t size; /* total size of the buffer */
|
||||
@ -58,21 +56,19 @@ struct buffer_s
|
||||
* to the buffer. The data IS copied, so make sure if you allocated your
|
||||
* data buffer on the heap, delete it because you now have TWO copies.
|
||||
*/
|
||||
static struct bufline_s *
|
||||
makenewline (unsigned char *data, size_t length)
|
||||
static struct bufline_s *makenewline (unsigned char *data, size_t length)
|
||||
{
|
||||
struct bufline_s *newline;
|
||||
|
||||
assert (data != NULL);
|
||||
assert (length > 0);
|
||||
|
||||
newline = (struct bufline_s *)safemalloc (sizeof (struct bufline_s));
|
||||
newline = (struct bufline_s *) safemalloc (sizeof (struct bufline_s));
|
||||
if (!newline)
|
||||
return NULL;
|
||||
|
||||
newline->string = (unsigned char *)safemalloc (length);
|
||||
if (!newline->string)
|
||||
{
|
||||
newline->string = (unsigned char *) safemalloc (length);
|
||||
if (!newline->string) {
|
||||
safefree (newline);
|
||||
return NULL;
|
||||
}
|
||||
@ -91,8 +87,7 @@ makenewline (unsigned char *data, size_t length)
|
||||
/*
|
||||
* Free the allocated buffer line
|
||||
*/
|
||||
static void
|
||||
free_line (struct bufline_s *line)
|
||||
static void free_line (struct bufline_s *line)
|
||||
{
|
||||
assert (line != NULL);
|
||||
|
||||
@ -108,12 +103,11 @@ free_line (struct bufline_s *line)
|
||||
/*
|
||||
* Create a new buffer
|
||||
*/
|
||||
struct buffer_s *
|
||||
new_buffer (void)
|
||||
struct buffer_s *new_buffer (void)
|
||||
{
|
||||
struct buffer_s *buffptr;
|
||||
|
||||
buffptr = (struct buffer_s *)safemalloc (sizeof (struct buffer_s));
|
||||
buffptr = (struct buffer_s *) safemalloc (sizeof (struct buffer_s));
|
||||
if (!buffptr)
|
||||
return NULL;
|
||||
|
||||
@ -131,15 +125,13 @@ new_buffer (void)
|
||||
/*
|
||||
* Delete all the lines in the buffer and the buffer itself
|
||||
*/
|
||||
void
|
||||
delete_buffer (struct buffer_s *buffptr)
|
||||
void delete_buffer (struct buffer_s *buffptr)
|
||||
{
|
||||
struct bufline_s *next;
|
||||
|
||||
assert (buffptr != NULL);
|
||||
|
||||
while (BUFFER_HEAD (buffptr))
|
||||
{
|
||||
while (BUFFER_HEAD (buffptr)) {
|
||||
next = BUFFER_HEAD (buffptr)->next;
|
||||
free_line (BUFFER_HEAD (buffptr));
|
||||
BUFFER_HEAD (buffptr) = next;
|
||||
@ -151,8 +143,7 @@ delete_buffer (struct buffer_s *buffptr)
|
||||
/*
|
||||
* Return the current size of the buffer.
|
||||
*/
|
||||
size_t
|
||||
buffer_size (struct buffer_s *buffptr)
|
||||
size_t buffer_size (struct buffer_s *buffptr)
|
||||
{
|
||||
return buffptr->size;
|
||||
}
|
||||
@ -160,8 +151,7 @@ buffer_size (struct buffer_s *buffptr)
|
||||
/*
|
||||
* Push a new line on to the end of the buffer.
|
||||
*/
|
||||
int
|
||||
add_to_buffer (struct buffer_s *buffptr, unsigned char *data, size_t length)
|
||||
int add_to_buffer (struct buffer_s *buffptr, unsigned char *data, size_t length)
|
||||
{
|
||||
struct bufline_s *newline;
|
||||
|
||||
@ -186,8 +176,7 @@ add_to_buffer (struct buffer_s *buffptr, unsigned char *data, size_t length)
|
||||
|
||||
if (buffptr->size == 0)
|
||||
BUFFER_HEAD (buffptr) = BUFFER_TAIL (buffptr) = newline;
|
||||
else
|
||||
{
|
||||
else {
|
||||
BUFFER_TAIL (buffptr)->next = newline;
|
||||
BUFFER_TAIL (buffptr) = newline;
|
||||
}
|
||||
@ -200,8 +189,7 @@ add_to_buffer (struct buffer_s *buffptr, unsigned char *data, size_t length)
|
||||
/*
|
||||
* Remove the first line from the top of the buffer
|
||||
*/
|
||||
static struct bufline_s *
|
||||
remove_from_buffer (struct buffer_s *buffptr)
|
||||
static struct bufline_s *remove_from_buffer (struct buffer_s *buffptr)
|
||||
{
|
||||
struct bufline_s *line;
|
||||
|
||||
@ -221,8 +209,7 @@ remove_from_buffer (struct buffer_s *buffptr)
|
||||
* Takes a connection and returns the number of bytes read.
|
||||
*/
|
||||
#define READ_BUFFER_SIZE (1024 * 2)
|
||||
ssize_t
|
||||
read_buffer (int fd, struct buffer_s * buffptr)
|
||||
ssize_t read_buffer (int fd, struct buffer_s * buffptr)
|
||||
{
|
||||
ssize_t bytesin;
|
||||
unsigned char *buffer;
|
||||
@ -236,33 +223,25 @@ read_buffer (int fd, struct buffer_s * buffptr)
|
||||
if (buffptr->size >= MAXBUFFSIZE)
|
||||
return 0;
|
||||
|
||||
buffer = (unsigned char *)safemalloc (READ_BUFFER_SIZE);
|
||||
if (!buffer)
|
||||
{
|
||||
buffer = (unsigned char *) safemalloc (READ_BUFFER_SIZE);
|
||||
if (!buffer) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
bytesin = read (fd, buffer, READ_BUFFER_SIZE);
|
||||
|
||||
if (bytesin > 0)
|
||||
{
|
||||
if (add_to_buffer (buffptr, buffer, bytesin) < 0)
|
||||
{
|
||||
log_message (LOG_ERR, "readbuff: add_to_buffer() error.");
|
||||
if (bytesin > 0) {
|
||||
if (add_to_buffer (buffptr, buffer, bytesin) < 0) {
|
||||
log_message (LOG_ERR,
|
||||
"readbuff: add_to_buffer() error.");
|
||||
bytesin = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bytesin == 0)
|
||||
{
|
||||
} else {
|
||||
if (bytesin == 0) {
|
||||
/* connection was closed by client */
|
||||
bytesin = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
} else {
|
||||
switch (errno) {
|
||||
#ifdef EWOULDBLOCK
|
||||
case EWOULDBLOCK:
|
||||
#else
|
||||
@ -291,8 +270,7 @@ read_buffer (int fd, struct buffer_s * buffptr)
|
||||
* Write the bytes in the buffer to the socket.
|
||||
* Takes a connection and returns the number of bytes written.
|
||||
*/
|
||||
ssize_t
|
||||
write_buffer (int fd, struct buffer_s * buffptr)
|
||||
ssize_t write_buffer (int fd, struct buffer_s * buffptr)
|
||||
{
|
||||
ssize_t bytessent;
|
||||
struct bufline_s *line;
|
||||
@ -311,18 +289,14 @@ write_buffer (int fd, struct buffer_s * buffptr)
|
||||
send (fd, line->string + line->pos, line->length - line->pos,
|
||||
MSG_NOSIGNAL);
|
||||
|
||||
if (bytessent >= 0)
|
||||
{
|
||||
if (bytessent >= 0) {
|
||||
/* bytes sent, adjust buffer */
|
||||
line->pos += bytessent;
|
||||
if (line->pos == line->length)
|
||||
free_line (remove_from_buffer (buffptr));
|
||||
return bytessent;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
} else {
|
||||
switch (errno) {
|
||||
#ifdef EWOULDBLOCK
|
||||
case EWOULDBLOCK:
|
||||
#else
|
||||
@ -336,7 +310,8 @@ write_buffer (int fd, struct buffer_s * buffptr)
|
||||
case ENOMEM:
|
||||
log_message (LOG_ERR,
|
||||
"writebuff: write() error [NOBUFS/NOMEM] \"%s\" on "
|
||||
"file descriptor %d", strerror (errno), fd);
|
||||
"file descriptor %d", strerror (errno),
|
||||
fd);
|
||||
return 0;
|
||||
default:
|
||||
log_message (LOG_ERR,
|
||||
|
164
src/child.c
164
src/child.c
@ -37,10 +37,8 @@ static socklen_t addrlen;
|
||||
/*
|
||||
* Stores the internal data needed for each child (connection)
|
||||
*/
|
||||
enum child_status_t
|
||||
{ T_EMPTY, T_WAITING, T_CONNECTED };
|
||||
struct child_s
|
||||
{
|
||||
enum child_status_t { T_EMPTY, T_WAITING, T_CONNECTED };
|
||||
struct child_s {
|
||||
pid_t tid;
|
||||
unsigned int connects;
|
||||
enum child_status_t status;
|
||||
@ -52,8 +50,7 @@ struct child_s
|
||||
*/
|
||||
static struct child_s *child_ptr;
|
||||
|
||||
static struct child_config_s
|
||||
{
|
||||
static struct child_config_s {
|
||||
unsigned int maxclients, maxrequestsperchild;
|
||||
unsigned int maxspareservers, minspareservers, startservers;
|
||||
} child_config;
|
||||
@ -76,8 +73,7 @@ static unsigned int *servers_waiting; /* servers waiting for a connection */
|
||||
static struct flock lock_it, unlock_it;
|
||||
static int lock_fd = -1;
|
||||
|
||||
static void
|
||||
_child_lock_init (void)
|
||||
static void _child_lock_init (void)
|
||||
{
|
||||
char lock_file[] = "/tmp/tinyproxy.servers.lock.XXXXXX";
|
||||
|
||||
@ -100,13 +96,11 @@ _child_lock_init (void)
|
||||
unlock_it.l_len = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_child_lock_wait (void)
|
||||
static void _child_lock_wait (void)
|
||||
{
|
||||
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)
|
||||
continue;
|
||||
else
|
||||
@ -114,8 +108,7 @@ _child_lock_wait (void)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_child_lock_release (void)
|
||||
static void _child_lock_release (void)
|
||||
{
|
||||
if (fcntl (lock_fd, F_SETLKW, &unlock_it) < 0)
|
||||
return;
|
||||
@ -141,11 +134,9 @@ _child_lock_release (void)
|
||||
/*
|
||||
* Set the configuration values for the various child related settings.
|
||||
*/
|
||||
short int
|
||||
child_configure (child_config_t type, unsigned int val)
|
||||
short int child_configure (child_config_t type, unsigned int val)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
switch (type) {
|
||||
case CHILD_MAXCLIENTS:
|
||||
child_config.maxclients = val;
|
||||
break;
|
||||
@ -172,24 +163,22 @@ child_configure (child_config_t type, unsigned int val)
|
||||
/*
|
||||
* This is the main (per child) loop.
|
||||
*/
|
||||
static void
|
||||
child_main (struct child_s *ptr)
|
||||
static void child_main (struct child_s *ptr)
|
||||
{
|
||||
int connfd;
|
||||
struct sockaddr *cliaddr;
|
||||
socklen_t clilen;
|
||||
|
||||
cliaddr = (struct sockaddr *)safemalloc (addrlen);
|
||||
if (!cliaddr)
|
||||
{
|
||||
log_message (LOG_CRIT, "Could not allocate memory for child address.");
|
||||
cliaddr = (struct sockaddr *) safemalloc (addrlen);
|
||||
if (!cliaddr) {
|
||||
log_message (LOG_CRIT,
|
||||
"Could not allocate memory for child address.");
|
||||
exit (0);
|
||||
}
|
||||
|
||||
ptr->connects = 0;
|
||||
|
||||
while (!config.quit)
|
||||
{
|
||||
while (!config.quit) {
|
||||
ptr->status = T_WAITING;
|
||||
|
||||
clilen = addrlen;
|
||||
@ -201,22 +190,21 @@ child_main (struct child_s *ptr)
|
||||
* Enable the TINYPROXY_DEBUG environment variable if you
|
||||
* want to use the GDB debugger.
|
||||
*/
|
||||
if (getenv ("TINYPROXY_DEBUG"))
|
||||
{
|
||||
if (getenv ("TINYPROXY_DEBUG")) {
|
||||
/* Pause for 10 seconds to allow us to connect debugger */
|
||||
fprintf (stderr,
|
||||
"Process has accepted connection: %ld\n",
|
||||
(long int) ptr->tid);
|
||||
sleep (10);
|
||||
fprintf (stderr, "Continuing process: %ld\n", (long int) ptr->tid);
|
||||
fprintf (stderr, "Continuing process: %ld\n",
|
||||
(long int) ptr->tid);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Make sure no error occurred...
|
||||
*/
|
||||
if (connfd < 0)
|
||||
{
|
||||
if (connfd < 0) {
|
||||
log_message (LOG_ERR,
|
||||
"Accept returned an error (%s) ... retrying.",
|
||||
strerror (errno));
|
||||
@ -230,12 +218,10 @@ child_main (struct child_s *ptr)
|
||||
handle_connection (connfd);
|
||||
ptr->connects++;
|
||||
|
||||
if (child_config.maxrequestsperchild != 0)
|
||||
{
|
||||
if (child_config.maxrequestsperchild != 0) {
|
||||
DEBUG2 ("%u connections so far...", ptr->connects);
|
||||
|
||||
if (ptr->connects == child_config.maxrequestsperchild)
|
||||
{
|
||||
if (ptr->connects == child_config.maxrequestsperchild) {
|
||||
log_message (LOG_NOTICE,
|
||||
"Child has reached MaxRequestsPerChild (%u). "
|
||||
"Killing child.", ptr->connects);
|
||||
@ -244,8 +230,7 @@ child_main (struct child_s *ptr)
|
||||
}
|
||||
|
||||
SERVER_COUNT_LOCK ();
|
||||
if (*servers_waiting > child_config.maxspareservers)
|
||||
{
|
||||
if (*servers_waiting > child_config.maxspareservers) {
|
||||
/*
|
||||
* There are too many spare children, kill ourself
|
||||
* off.
|
||||
@ -253,13 +238,12 @@ child_main (struct child_s *ptr)
|
||||
log_message (LOG_NOTICE,
|
||||
"Waiting servers (%d) exceeds MaxSpareServers (%d). "
|
||||
"Killing child.",
|
||||
*servers_waiting, child_config.maxspareservers);
|
||||
*servers_waiting,
|
||||
child_config.maxspareservers);
|
||||
SERVER_COUNT_UNLOCK ();
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
SERVER_COUNT_UNLOCK ();
|
||||
}
|
||||
|
||||
@ -276,8 +260,7 @@ child_main (struct child_s *ptr)
|
||||
* Fork a child "child" (or in our case a process) and then start up the
|
||||
* child_main() function.
|
||||
*/
|
||||
static pid_t
|
||||
child_make (struct child_s *ptr)
|
||||
static pid_t child_make (struct child_s *ptr)
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
@ -298,8 +281,7 @@ child_make (struct child_s *ptr)
|
||||
/*
|
||||
* Create a pool of children to handle incoming connections
|
||||
*/
|
||||
short int
|
||||
child_pool_create (void)
|
||||
short int child_pool_create (void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@ -308,33 +290,33 @@ child_pool_create (void)
|
||||
* variable determines the size of the array created for children
|
||||
* later on.
|
||||
*/
|
||||
if (child_config.maxclients == 0)
|
||||
{
|
||||
if (child_config.maxclients == 0) {
|
||||
log_message (LOG_ERR,
|
||||
"child_pool_create: \"MaxClients\" must be "
|
||||
"greater than zero.");
|
||||
return -1;
|
||||
}
|
||||
if (child_config.startservers == 0)
|
||||
{
|
||||
if (child_config.startservers == 0) {
|
||||
log_message (LOG_ERR,
|
||||
"child_pool_create: \"StartServers\" must be "
|
||||
"greater than zero.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
child_ptr = (struct child_s *)calloc_shared_memory (child_config.maxclients,
|
||||
child_ptr =
|
||||
(struct child_s *) calloc_shared_memory (child_config.maxclients,
|
||||
sizeof (struct child_s));
|
||||
if (!child_ptr)
|
||||
{
|
||||
log_message (LOG_ERR, "Could not allocate memory for children.");
|
||||
if (!child_ptr) {
|
||||
log_message (LOG_ERR,
|
||||
"Could not allocate memory for children.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
servers_waiting = (unsigned int *)malloc_shared_memory (sizeof (unsigned int));
|
||||
if (servers_waiting == MAP_FAILED)
|
||||
{
|
||||
log_message (LOG_ERR, "Could not allocate memory for child counting.");
|
||||
servers_waiting =
|
||||
(unsigned int *) malloc_shared_memory (sizeof (unsigned int));
|
||||
if (servers_waiting == MAP_FAILED) {
|
||||
log_message (LOG_ERR,
|
||||
"Could not allocate memory for child counting.");
|
||||
return -1;
|
||||
}
|
||||
*servers_waiting = 0;
|
||||
@ -345,36 +327,31 @@ child_pool_create (void)
|
||||
*/
|
||||
_child_lock_init ();
|
||||
|
||||
if (child_config.startservers > child_config.maxclients)
|
||||
{
|
||||
if (child_config.startservers > child_config.maxclients) {
|
||||
log_message (LOG_WARNING,
|
||||
"Can not start more than \"MaxClients\" servers. "
|
||||
"Starting %u servers instead.", child_config.maxclients);
|
||||
"Starting %u servers instead.",
|
||||
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].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,
|
||||
child_config.startservers);
|
||||
child_ptr[i].status = T_WAITING;
|
||||
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,
|
||||
"Could not create child number %d of %d",
|
||||
i, child_config.startservers);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
log_message (LOG_INFO,
|
||||
"Creating child number %d of %d ...",
|
||||
i + 1, child_config.startservers);
|
||||
@ -392,36 +369,33 @@ child_pool_create (void)
|
||||
* Keep the proper number of servers running. This is the birth of the
|
||||
* servers. It monitors this at least once a second.
|
||||
*/
|
||||
void
|
||||
child_main_loop (void)
|
||||
void child_main_loop (void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (1) {
|
||||
if (config.quit)
|
||||
return;
|
||||
|
||||
/* If there are not enough spare servers, create more */
|
||||
SERVER_COUNT_LOCK ();
|
||||
if (*servers_waiting < child_config.minspareservers)
|
||||
{
|
||||
if (*servers_waiting < child_config.minspareservers) {
|
||||
log_message (LOG_NOTICE,
|
||||
"Waiting servers (%d) is less than MinSpareServers (%d). "
|
||||
"Creating new child.",
|
||||
*servers_waiting, child_config.minspareservers);
|
||||
*servers_waiting,
|
||||
child_config.minspareservers);
|
||||
|
||||
SERVER_COUNT_UNLOCK ();
|
||||
|
||||
for (i = 0; i != child_config.maxclients; i++)
|
||||
{
|
||||
if (child_ptr[i].status == T_EMPTY)
|
||||
{
|
||||
for (i = 0; i != child_config.maxclients; i++) {
|
||||
if (child_ptr[i].status == T_EMPTY) {
|
||||
child_ptr[i].status = T_WAITING;
|
||||
child_ptr[i].tid = child_make (&child_ptr[i]);
|
||||
if (child_ptr[i].tid < 0)
|
||||
{
|
||||
log_message (LOG_NOTICE, "Could not create child");
|
||||
child_ptr[i].tid =
|
||||
child_make (&child_ptr[i]);
|
||||
if (child_ptr[i].tid < 0) {
|
||||
log_message (LOG_NOTICE,
|
||||
"Could not create child");
|
||||
|
||||
child_ptr[i].status = T_EMPTY;
|
||||
break;
|
||||
@ -432,22 +406,18 @@ child_main_loop (void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
SERVER_COUNT_UNLOCK ();
|
||||
}
|
||||
|
||||
sleep (5);
|
||||
|
||||
/* Handle log rotation if it was requested */
|
||||
if (received_sighup)
|
||||
{
|
||||
if (received_sighup) {
|
||||
truncate_log_file ();
|
||||
|
||||
#ifdef FILTER_ENABLE
|
||||
if (config.filter)
|
||||
{
|
||||
if (config.filter) {
|
||||
filter_destroy ();
|
||||
filter_init ();
|
||||
}
|
||||
@ -462,27 +432,23 @@ child_main_loop (void)
|
||||
/*
|
||||
* Go through all the non-empty children and cancel them.
|
||||
*/
|
||||
void
|
||||
child_kill_children (void)
|
||||
void child_kill_children (void)
|
||||
{
|
||||
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)
|
||||
kill (child_ptr[i].tid, SIGTERM);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
child_listening_sock (uint16_t port)
|
||||
int child_listening_sock (uint16_t port)
|
||||
{
|
||||
listenfd = listen_sock (port, &addrlen);
|
||||
return listenfd;
|
||||
}
|
||||
|
||||
void
|
||||
child_close_sock (void)
|
||||
void child_close_sock (void)
|
||||
{
|
||||
close (listenfd);
|
||||
}
|
||||
|
@ -21,8 +21,7 @@
|
||||
#ifndef TINYPROXY_CHILD_H
|
||||
#define TINYPROXY_CHILD_H
|
||||
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
CHILD_MAXCLIENTS,
|
||||
CHILD_MAXSPARESERVERS,
|
||||
CHILD_MINSPARESERVERS,
|
||||
|
217
src/conffile.c
217
src/conffile.c
@ -66,8 +66,7 @@
|
||||
* All configuration handling functions are REQUIRED to be defined
|
||||
* with the same function template as below.
|
||||
*/
|
||||
typedef int (*CONFFILE_HANDLER) (struct config_s *, const char *,
|
||||
regmatch_t[]);
|
||||
typedef int (*CONFFILE_HANDLER) (struct config_s *, const char *, regmatch_t[]);
|
||||
|
||||
/*
|
||||
* Define the pattern used by any directive handling function. The
|
||||
@ -88,8 +87,7 @@ typedef int (*CONFFILE_HANDLER) (struct config_s *, const char *,
|
||||
* List all the handling functions. These are defined later, but they need
|
||||
* to be in-scope before the big structure below.
|
||||
*/
|
||||
static
|
||||
HANDLE_FUNC (handle_nop)
|
||||
static HANDLE_FUNC (handle_nop)
|
||||
{
|
||||
return 0;
|
||||
} /* do nothing function */
|
||||
@ -159,17 +157,17 @@ static HANDLE_FUNC (handle_upstream_no);
|
||||
* for internal use, a pointer to the compiled regex so it only needs
|
||||
* to be compiled one.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
const char *re;
|
||||
CONFFILE_HANDLER handler;
|
||||
regex_t *cre;
|
||||
} directives[] =
|
||||
{
|
||||
} directives[] = {
|
||||
/* comments */
|
||||
{ BEGIN "#", handle_nop, NULL },
|
||||
{
|
||||
BEGIN "#", handle_nop, NULL},
|
||||
/* blank lines */
|
||||
{ "^[[:space:]]+$", handle_nop, NULL },
|
||||
{
|
||||
"^[[:space:]]+$", handle_nop, NULL},
|
||||
/* string arguments */
|
||||
STDCONF ("logfile", STR, handle_logfile),
|
||||
STDCONF ("pidfile", STR, handle_pidfile),
|
||||
@ -218,12 +216,10 @@ struct
|
||||
#endif
|
||||
#ifdef UPSTREAM_SUPPORT
|
||||
/* upstream is rather complicated */
|
||||
{ BEGIN "(no" WS "upstream)" WS STR END, handle_upstream_no, NULL },
|
||||
{
|
||||
BEGIN "(upstream)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR ")?" END,
|
||||
handle_upstream,
|
||||
NULL
|
||||
},
|
||||
BEGIN "(no" WS "upstream)" WS STR END, handle_upstream_no, NULL}, {
|
||||
BEGIN "(upstream)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR
|
||||
")?" END, handle_upstream, NULL},
|
||||
#endif
|
||||
/* loglevel */
|
||||
STDCONF ("loglevel", "(critical|error|warning|notice|connect|info)",
|
||||
@ -238,22 +234,21 @@ const unsigned int ndirectives = sizeof (directives) / sizeof (directives[0]);
|
||||
*
|
||||
* Returns 0 on success; negative upon failure.
|
||||
*/
|
||||
int
|
||||
config_compile (void)
|
||||
int config_compile (void)
|
||||
{
|
||||
unsigned int i, r;
|
||||
|
||||
for (i = 0; i != ndirectives; ++i)
|
||||
{
|
||||
for (i = 0; i != ndirectives; ++i) {
|
||||
assert (directives[i].handler);
|
||||
assert (!directives[i].cre);
|
||||
|
||||
directives[i].cre = (regex_t *)safemalloc (sizeof (regex_t));
|
||||
directives[i].cre = (regex_t *) safemalloc (sizeof (regex_t));
|
||||
if (!directives[i].cre)
|
||||
return -1;
|
||||
|
||||
r = regcomp (directives[i].cre,
|
||||
directives[i].re, REG_EXTENDED | REG_ICASE | REG_NEWLINE);
|
||||
directives[i].re,
|
||||
REG_EXTENDED | REG_ICASE | REG_NEWLINE);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
@ -268,18 +263,17 @@ config_compile (void)
|
||||
* Returns 0 if a match was found and successfully processed; otherwise,
|
||||
* a negative number is returned.
|
||||
*/
|
||||
static int
|
||||
check_match (struct config_s *conf, const char *line)
|
||||
static int check_match (struct config_s *conf, const char *line)
|
||||
{
|
||||
regmatch_t match[RE_MAX_MATCHES];
|
||||
unsigned int i;
|
||||
|
||||
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))
|
||||
if (!regexec
|
||||
(directives[i].cre, line, RE_MAX_MATCHES, match, 0))
|
||||
return (*directives[i].handler) (conf, line, match);
|
||||
}
|
||||
|
||||
@ -289,16 +283,13 @@ check_match (struct config_s *conf, const char *line)
|
||||
/*
|
||||
* Parse the previously opened configuration stream.
|
||||
*/
|
||||
int
|
||||
config_parse (struct config_s *conf, FILE * f)
|
||||
int config_parse (struct config_s *conf, FILE * f)
|
||||
{
|
||||
char buffer[1024]; /* 1KB lines should be plenty */
|
||||
unsigned long lineno = 1;
|
||||
|
||||
while (fgets (buffer, sizeof (buffer), f))
|
||||
{
|
||||
if (check_match (conf, buffer))
|
||||
{
|
||||
while (fgets (buffer, sizeof (buffer), f)) {
|
||||
if (check_match (conf, buffer)) {
|
||||
printf ("Syntax error on line %ld\n", lineno);
|
||||
return 1;
|
||||
}
|
||||
@ -314,8 +305,7 @@ config_parse (struct config_s *conf, FILE * f)
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
static char *
|
||||
get_string_arg (const char *line, regmatch_t * match)
|
||||
static char *get_string_arg (const char *line, regmatch_t * match)
|
||||
{
|
||||
char *p;
|
||||
const unsigned int len = match->rm_eo - match->rm_so;
|
||||
@ -323,7 +313,7 @@ get_string_arg (const char *line, regmatch_t * match)
|
||||
assert (line);
|
||||
assert (len > 0);
|
||||
|
||||
p = (char *)safemalloc (len + 1);
|
||||
p = (char *) safemalloc (len + 1);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
@ -332,8 +322,7 @@ get_string_arg (const char *line, regmatch_t * match)
|
||||
return p;
|
||||
}
|
||||
|
||||
static int
|
||||
set_string_arg (char **var, const char *line, regmatch_t * match)
|
||||
static int set_string_arg (char **var, const char *line, regmatch_t * match)
|
||||
{
|
||||
char *arg = get_string_arg (line, match);
|
||||
|
||||
@ -344,8 +333,7 @@ set_string_arg (char **var, const char *line, regmatch_t * match)
|
||||
return *var ? 0 : -1;
|
||||
}
|
||||
|
||||
static int
|
||||
get_bool_arg (const char *line, regmatch_t * match)
|
||||
static int get_bool_arg (const char *line, regmatch_t * match)
|
||||
{
|
||||
const char *p = line + match->rm_so;
|
||||
|
||||
@ -408,20 +396,17 @@ set_int_arg (unsigned long int *var, const char *line, regmatch_t * match)
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_logfile)
|
||||
static HANDLE_FUNC (handle_logfile)
|
||||
{
|
||||
return set_string_arg (&conf->logf_name, line, &match[2]);
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_pidfile)
|
||||
static HANDLE_FUNC (handle_pidfile)
|
||||
{
|
||||
return set_string_arg (&conf->pidpath, line, &match[2]);
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_anonymous)
|
||||
static HANDLE_FUNC (handle_anonymous)
|
||||
{
|
||||
char *arg = get_string_arg (line, &match[2]);
|
||||
|
||||
@ -433,32 +418,29 @@ HANDLE_FUNC (handle_anonymous)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_viaproxyname)
|
||||
static HANDLE_FUNC (handle_viaproxyname)
|
||||
{
|
||||
int r = set_string_arg (&conf->via_proxy_name, line, &match[2]);
|
||||
|
||||
if (r)
|
||||
return r;
|
||||
log_message (LOG_INFO,
|
||||
"Setting \"Via\" header proxy to %s", conf->via_proxy_name);
|
||||
"Setting \"Via\" header proxy to %s",
|
||||
conf->via_proxy_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_defaulterrorfile)
|
||||
static HANDLE_FUNC (handle_defaulterrorfile)
|
||||
{
|
||||
return set_string_arg (&conf->errorpage_undef, line, &match[2]);
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_statfile)
|
||||
static HANDLE_FUNC (handle_statfile)
|
||||
{
|
||||
return set_string_arg (&conf->statpage, line, &match[2]);
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_stathost)
|
||||
static HANDLE_FUNC (handle_stathost)
|
||||
{
|
||||
int r = set_string_arg (&conf->stathost, line, &match[2]);
|
||||
|
||||
@ -468,8 +450,7 @@ HANDLE_FUNC (handle_stathost)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_xtinyproxy)
|
||||
static HANDLE_FUNC (handle_xtinyproxy)
|
||||
{
|
||||
#ifdef XTINYPROXY_ENABLE
|
||||
return set_string_arg (&conf->my_domain, line, &match[2]);
|
||||
@ -480,8 +461,7 @@ HANDLE_FUNC (handle_xtinyproxy)
|
||||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_syslog)
|
||||
static HANDLE_FUNC (handle_syslog)
|
||||
{
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
return set_bool_arg (&conf->syslog, line, &match[2]);
|
||||
@ -491,8 +471,7 @@ HANDLE_FUNC (handle_syslog)
|
||||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_bindsame)
|
||||
static HANDLE_FUNC (handle_bindsame)
|
||||
{
|
||||
int r = set_bool_arg (&conf->bindsame, line, &match[2]);
|
||||
|
||||
@ -502,74 +481,65 @@ HANDLE_FUNC (handle_bindsame)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_port)
|
||||
static HANDLE_FUNC (handle_port)
|
||||
{
|
||||
return set_int_arg ((unsigned long int *) &conf->port, line, &match[2]);
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_maxclients)
|
||||
static HANDLE_FUNC (handle_maxclients)
|
||||
{
|
||||
child_configure (CHILD_MAXCLIENTS, get_int_arg (line, &match[2]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_maxspareservers)
|
||||
static HANDLE_FUNC (handle_maxspareservers)
|
||||
{
|
||||
child_configure (CHILD_MAXSPARESERVERS, get_int_arg (line, &match[2]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_minspareservers)
|
||||
static HANDLE_FUNC (handle_minspareservers)
|
||||
{
|
||||
child_configure (CHILD_MINSPARESERVERS, get_int_arg (line, &match[2]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_startservers)
|
||||
static HANDLE_FUNC (handle_startservers)
|
||||
{
|
||||
child_configure (CHILD_STARTSERVERS, get_int_arg (line, &match[2]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_maxrequestsperchild)
|
||||
static HANDLE_FUNC (handle_maxrequestsperchild)
|
||||
{
|
||||
child_configure (CHILD_MAXREQUESTSPERCHILD, get_int_arg (line, &match[2]));
|
||||
child_configure (CHILD_MAXREQUESTSPERCHILD,
|
||||
get_int_arg (line, &match[2]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_timeout)
|
||||
static HANDLE_FUNC (handle_timeout)
|
||||
{
|
||||
return set_int_arg ((unsigned long int *) &conf->idletimeout, line, &match[2]);
|
||||
return set_int_arg ((unsigned long int *) &conf->idletimeout, line,
|
||||
&match[2]);
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_connectport)
|
||||
static HANDLE_FUNC (handle_connectport)
|
||||
{
|
||||
add_connect_port_allowed (get_int_arg (line, &match[2]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_user)
|
||||
static HANDLE_FUNC (handle_user)
|
||||
{
|
||||
return set_string_arg (&conf->user, line, &match[2]);
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_group)
|
||||
static HANDLE_FUNC (handle_group)
|
||||
{
|
||||
return set_string_arg (&conf->group, line, &match[2]);
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_allow)
|
||||
static HANDLE_FUNC (handle_allow)
|
||||
{
|
||||
char *arg = get_string_arg (line, &match[2]);
|
||||
|
||||
@ -578,8 +548,7 @@ HANDLE_FUNC (handle_allow)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_deny)
|
||||
static HANDLE_FUNC (handle_deny)
|
||||
{
|
||||
char *arg = get_string_arg (line, &match[2]);
|
||||
|
||||
@ -588,8 +557,7 @@ HANDLE_FUNC (handle_deny)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_bind)
|
||||
static HANDLE_FUNC (handle_bind)
|
||||
{
|
||||
#ifndef TRANSPARENT_PROXY
|
||||
int r = set_string_arg (&conf->bind_address, line, &match[2]);
|
||||
@ -606,8 +574,7 @@ HANDLE_FUNC (handle_bind)
|
||||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_listen)
|
||||
static HANDLE_FUNC (handle_listen)
|
||||
{
|
||||
int r = set_string_arg (&conf->ipAddr, line, &match[2]);
|
||||
|
||||
@ -617,8 +584,7 @@ HANDLE_FUNC (handle_listen)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_errorfile)
|
||||
static HANDLE_FUNC (handle_errorfile)
|
||||
{
|
||||
/*
|
||||
* Because an integer is defined as ((0x)?[[:digit:]]+) _two_
|
||||
@ -638,8 +604,7 @@ HANDLE_FUNC (handle_errorfile)
|
||||
/*
|
||||
* Log level's strings.
|
||||
*/
|
||||
struct log_levels_s
|
||||
{
|
||||
struct log_levels_s {
|
||||
const char *string;
|
||||
int level;
|
||||
};
|
||||
@ -652,8 +617,7 @@ static struct log_levels_s log_levels[] = {
|
||||
{"info", LOG_INFO}
|
||||
};
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_loglevel)
|
||||
static HANDLE_FUNC (handle_loglevel)
|
||||
{
|
||||
static const unsigned int nlevels =
|
||||
sizeof (log_levels) / sizeof (log_levels[0]);
|
||||
@ -661,10 +625,8 @@ HANDLE_FUNC (handle_loglevel)
|
||||
|
||||
char *arg = get_string_arg (line, &match[2]);
|
||||
|
||||
for (i = 0; i != nlevels; ++i)
|
||||
{
|
||||
if (!strcasecmp (arg, log_levels[i].string))
|
||||
{
|
||||
for (i = 0; i != nlevels; ++i) {
|
||||
if (!strcasecmp (arg, log_levels[i].string)) {
|
||||
set_log_level (log_levels[i].level);
|
||||
safefree (arg);
|
||||
return 0;
|
||||
@ -676,26 +638,22 @@ HANDLE_FUNC (handle_loglevel)
|
||||
}
|
||||
|
||||
#ifdef FILTER_ENABLE
|
||||
static
|
||||
HANDLE_FUNC (handle_filter)
|
||||
static HANDLE_FUNC (handle_filter)
|
||||
{
|
||||
return set_string_arg (&conf->filter, line, &match[2]);
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_filterurls)
|
||||
static HANDLE_FUNC (handle_filterurls)
|
||||
{
|
||||
return set_bool_arg (&conf->filter_url, line, &match[2]);
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_filterextended)
|
||||
static HANDLE_FUNC (handle_filterextended)
|
||||
{
|
||||
return set_bool_arg (&conf->filter_extended, line, &match[2]);
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_filterdefaultdeny)
|
||||
static HANDLE_FUNC (handle_filterdefaultdeny)
|
||||
{
|
||||
assert (match[2].rm_so != -1);
|
||||
|
||||
@ -704,34 +662,29 @@ HANDLE_FUNC (handle_filterdefaultdeny)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_filtercasesensitive)
|
||||
static HANDLE_FUNC (handle_filtercasesensitive)
|
||||
{
|
||||
return set_bool_arg (&conf->filter_casesensitive, line, &match[2]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef REVERSE_SUPPORT
|
||||
static
|
||||
HANDLE_FUNC (handle_reverseonly)
|
||||
static HANDLE_FUNC (handle_reverseonly)
|
||||
{
|
||||
return set_bool_arg (&conf->reverseonly, line, &match[2]);
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_reversemagic)
|
||||
static HANDLE_FUNC (handle_reversemagic)
|
||||
{
|
||||
return set_bool_arg (&conf->reversemagic, line, &match[2]);
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_reversebaseurl)
|
||||
static HANDLE_FUNC (handle_reversebaseurl)
|
||||
{
|
||||
return set_string_arg (&conf->reversebaseurl, line, &match[2]);
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_reversepath)
|
||||
static HANDLE_FUNC (handle_reversepath)
|
||||
{
|
||||
/*
|
||||
* The second string argument is optional.
|
||||
@ -742,20 +695,16 @@ HANDLE_FUNC (handle_reversepath)
|
||||
if (!arg1)
|
||||
return -1;
|
||||
|
||||
if (match[3].rm_so != -1)
|
||||
{
|
||||
if (match[3].rm_so != -1) {
|
||||
arg2 = get_string_arg (line, &match[3]);
|
||||
if (!arg2)
|
||||
{
|
||||
if (!arg2) {
|
||||
safefree (arg1);
|
||||
return -1;
|
||||
}
|
||||
reversepath_add (arg1, arg2);
|
||||
safefree (arg1);
|
||||
safefree (arg2);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
reversepath_add (NULL, arg1);
|
||||
safefree (arg1);
|
||||
}
|
||||
@ -764,8 +713,7 @@ HANDLE_FUNC (handle_reversepath)
|
||||
#endif
|
||||
|
||||
#ifdef UPSTREAM_SUPPORT
|
||||
static
|
||||
HANDLE_FUNC (handle_upstream)
|
||||
static HANDLE_FUNC (handle_upstream)
|
||||
{
|
||||
char *ip;
|
||||
int port;
|
||||
@ -774,19 +722,15 @@ HANDLE_FUNC (handle_upstream)
|
||||
ip = get_string_arg (line, &match[2]);
|
||||
if (!ip)
|
||||
return -1;
|
||||
port = (int)get_int_arg (line, &match[7]);
|
||||
port = (int) 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)
|
||||
{
|
||||
if (domain) {
|
||||
upstream_add (ip, port, domain);
|
||||
safefree (domain);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
upstream_add (ip, port, NULL);
|
||||
}
|
||||
|
||||
@ -795,8 +739,7 @@ HANDLE_FUNC (handle_upstream)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE_FUNC (handle_upstream_no)
|
||||
static HANDLE_FUNC (handle_upstream_no)
|
||||
{
|
||||
char *domain;
|
||||
|
||||
|
@ -30,8 +30,8 @@
|
||||
#include "log.h"
|
||||
#include "stats.h"
|
||||
|
||||
struct conn_s *
|
||||
initialize_conn (int client_fd, const char *ipaddr, const char *string_addr,
|
||||
struct conn_s *initialize_conn (int client_fd, const char *ipaddr,
|
||||
const char *string_addr,
|
||||
const char *sock_ipaddr)
|
||||
{
|
||||
struct conn_s *connptr;
|
||||
@ -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.
|
||||
*/
|
||||
connptr = (struct conn_s *)safemalloc (sizeof (struct conn_s));
|
||||
connptr = (struct conn_s *) safemalloc (sizeof (struct conn_s));
|
||||
if (!connptr)
|
||||
goto error_exit;
|
||||
|
||||
@ -102,8 +102,7 @@ error_exit:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
destroy_conn (struct conn_s *connptr)
|
||||
void destroy_conn (struct conn_s *connptr)
|
||||
{
|
||||
assert (connptr != NULL);
|
||||
|
||||
|
@ -27,8 +27,7 @@
|
||||
/*
|
||||
* Connection Definition
|
||||
*/
|
||||
struct conn_s
|
||||
{
|
||||
struct conn_s {
|
||||
int client_fd;
|
||||
int server_fd;
|
||||
|
||||
@ -52,8 +51,7 @@ struct conn_s
|
||||
char *error_string;
|
||||
|
||||
/* A Content-Length value from the remote server */
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
long int server;
|
||||
long int client;
|
||||
} content_length;
|
||||
@ -72,8 +70,7 @@ struct conn_s
|
||||
/*
|
||||
* Store the incoming request's HTTP protocol.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
unsigned int major;
|
||||
unsigned int minor;
|
||||
} protocol;
|
||||
|
13
src/daemon.c
13
src/daemon.c
@ -29,8 +29,7 @@
|
||||
* Fork a child process and then kill the parent so make the calling
|
||||
* program a daemon process.
|
||||
*/
|
||||
void
|
||||
makedaemon (void)
|
||||
void makedaemon (void)
|
||||
{
|
||||
if (fork () != 0)
|
||||
exit (0);
|
||||
@ -59,22 +58,18 @@ makedaemon (void)
|
||||
* Pass a signal number and a signal handling function into this function
|
||||
* to handle signals sent to the process.
|
||||
*/
|
||||
signal_func *
|
||||
set_signal_handler (int signo, signal_func * func)
|
||||
signal_func *set_signal_handler (int signo, signal_func * func)
|
||||
{
|
||||
struct sigaction act, oact;
|
||||
|
||||
act.sa_handler = func;
|
||||
sigemptyset (&act.sa_mask);
|
||||
act.sa_flags = 0;
|
||||
if (signo == SIGALRM)
|
||||
{
|
||||
if (signo == SIGALRM) {
|
||||
#ifdef SA_INTERRUPT
|
||||
act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
#ifdef SA_RESTART
|
||||
act.sa_flags |= SA_RESTART; /* SVR4, 4.4BSD */
|
||||
#endif
|
||||
|
90
src/filter.c
90
src/filter.c
@ -33,8 +33,7 @@
|
||||
|
||||
static int err;
|
||||
|
||||
struct filter_list
|
||||
{
|
||||
struct filter_list {
|
||||
struct filter_list *next;
|
||||
char *pat;
|
||||
regex_t *cpat;
|
||||
@ -47,8 +46,7 @@ static filter_policy_t default_policy = FILTER_DEFAULT_ALLOW;
|
||||
/*
|
||||
* Initializes a linked list of strings containing hosts/urls to be filtered
|
||||
*/
|
||||
void
|
||||
filter_init (void)
|
||||
void filter_init (void)
|
||||
{
|
||||
FILE *fd;
|
||||
struct filter_list *p;
|
||||
@ -56,11 +54,9 @@ filter_init (void)
|
||||
char *s;
|
||||
int cflags;
|
||||
|
||||
if (!fl && !already_init)
|
||||
{
|
||||
if (!fl && !already_init) {
|
||||
fd = fopen (config.filter, "r");
|
||||
if (fd)
|
||||
{
|
||||
if (fd) {
|
||||
p = NULL;
|
||||
|
||||
cflags = REG_NEWLINE | REG_NOSUB;
|
||||
@ -69,25 +65,23 @@ filter_init (void)
|
||||
if (!config.filter_casesensitive)
|
||||
cflags |= REG_ICASE;
|
||||
|
||||
while (fgets (buf, FILTER_BUFFER_LEN, fd))
|
||||
{
|
||||
while (fgets (buf, FILTER_BUFFER_LEN, fd)) {
|
||||
/*
|
||||
* Remove any trailing white space and
|
||||
* comments.
|
||||
*/
|
||||
s = buf;
|
||||
while (*s)
|
||||
{
|
||||
while (*s) {
|
||||
if (isspace ((unsigned char) *s))
|
||||
break;
|
||||
if (*s == '#')
|
||||
{
|
||||
if (*s == '#') {
|
||||
/*
|
||||
* If the '#' char is preceeded by
|
||||
* an escape, it's not a comment
|
||||
* string.
|
||||
*/
|
||||
if (s == buf || *(s - 1) != '\\')
|
||||
if (s == buf
|
||||
|| *(s - 1) != '\\')
|
||||
break;
|
||||
}
|
||||
++s;
|
||||
@ -104,26 +98,32 @@ filter_init (void)
|
||||
continue;
|
||||
|
||||
if (!p) /* head of list */
|
||||
fl = p = (struct filter_list *)safecalloc (1,
|
||||
sizeof (struct filter_list));
|
||||
else
|
||||
{ /* next entry */
|
||||
p->next = (struct filter_list *)safecalloc (1,
|
||||
sizeof (struct filter_list));
|
||||
fl = p =
|
||||
(struct filter_list *)
|
||||
safecalloc (1,
|
||||
sizeof (struct
|
||||
filter_list));
|
||||
else { /* next entry */
|
||||
p->next =
|
||||
(struct filter_list *)
|
||||
safecalloc (1,
|
||||
sizeof (struct
|
||||
filter_list));
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
p->pat = safestrdup (s);
|
||||
p->cpat = (regex_t *)safemalloc (sizeof (regex_t));
|
||||
if ((err = regcomp (p->cpat, p->pat, cflags)) != 0)
|
||||
{
|
||||
fprintf (stderr, "Bad regex in %s: %s\n",
|
||||
p->cpat =
|
||||
(regex_t *) safemalloc (sizeof (regex_t));
|
||||
if ((err =
|
||||
regcomp (p->cpat, p->pat, cflags)) != 0) {
|
||||
fprintf (stderr,
|
||||
"Bad regex in %s: %s\n",
|
||||
config.filter, p->pat);
|
||||
exit (EX_DATAERR);
|
||||
}
|
||||
}
|
||||
if (ferror (fd))
|
||||
{
|
||||
if (ferror (fd)) {
|
||||
perror ("fgets");
|
||||
exit (EX_DATAERR);
|
||||
}
|
||||
@ -135,15 +135,12 @@ filter_init (void)
|
||||
}
|
||||
|
||||
/* unlink the list */
|
||||
void
|
||||
filter_destroy (void)
|
||||
void filter_destroy (void)
|
||||
{
|
||||
struct filter_list *p, *q;
|
||||
|
||||
if (already_init)
|
||||
{
|
||||
for (p = q = fl; p; p = q)
|
||||
{
|
||||
if (already_init) {
|
||||
for (p = q = fl; p; p = q) {
|
||||
regfree (p->cpat);
|
||||
safefree (p->cpat);
|
||||
safefree (p->pat);
|
||||
@ -156,8 +153,7 @@ filter_destroy (void)
|
||||
}
|
||||
|
||||
/* Return 0 to allow, non-zero to block */
|
||||
int
|
||||
filter_domain (const char *host)
|
||||
int filter_domain (const char *host)
|
||||
{
|
||||
struct filter_list *p;
|
||||
int result;
|
||||
@ -165,12 +161,11 @@ filter_domain (const char *host)
|
||||
if (!fl || !already_init)
|
||||
goto COMMON_EXIT;
|
||||
|
||||
for (p = fl; p; p = p->next)
|
||||
{
|
||||
result = regexec (p->cpat, host, (size_t) 0, (regmatch_t *) 0, 0);
|
||||
for (p = fl; p; p = p->next) {
|
||||
result =
|
||||
regexec (p->cpat, host, (size_t) 0, (regmatch_t *) 0, 0);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
if (result == 0) {
|
||||
if (default_policy == FILTER_DEFAULT_ALLOW)
|
||||
return 1;
|
||||
else
|
||||
@ -186,8 +181,7 @@ COMMON_EXIT:
|
||||
}
|
||||
|
||||
/* returns 0 to allow, non-zero to block */
|
||||
int
|
||||
filter_url (const char *url)
|
||||
int filter_url (const char *url)
|
||||
{
|
||||
struct filter_list *p;
|
||||
int result;
|
||||
@ -195,12 +189,11 @@ filter_url (const char *url)
|
||||
if (!fl || !already_init)
|
||||
goto COMMON_EXIT;
|
||||
|
||||
for (p = fl; p; p = p->next)
|
||||
{
|
||||
result = regexec (p->cpat, url, (size_t) 0, (regmatch_t *) 0, 0);
|
||||
for (p = fl; p; p = p->next) {
|
||||
result =
|
||||
regexec (p->cpat, url, (size_t) 0, (regmatch_t *) 0, 0);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
if (result == 0) {
|
||||
if (default_policy == FILTER_DEFAULT_ALLOW)
|
||||
return 1;
|
||||
else
|
||||
@ -218,8 +211,7 @@ COMMON_EXIT:
|
||||
/*
|
||||
* Set the default filtering policy
|
||||
*/
|
||||
void
|
||||
filter_set_default_policy (filter_policy_t policy)
|
||||
void filter_set_default_policy (filter_policy_t policy)
|
||||
{
|
||||
default_policy = policy;
|
||||
}
|
||||
|
@ -21,8 +21,7 @@
|
||||
#ifndef _TINYPROXY_FILTER_H_
|
||||
#define _TINYPROXY_FILTER_H_
|
||||
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
FILTER_DEFAULT_ALLOW,
|
||||
FILTER_DEFAULT_DENY,
|
||||
} filter_policy_t;
|
||||
|
105
src/hashmap.c
105
src/hashmap.c
@ -37,8 +37,7 @@
|
||||
* internal use. It stores the number of buckets the hashmap was created
|
||||
* with.
|
||||
*/
|
||||
struct hashentry_s
|
||||
{
|
||||
struct hashentry_s {
|
||||
char *key;
|
||||
void *data;
|
||||
size_t len;
|
||||
@ -46,13 +45,11 @@ struct hashentry_s
|
||||
struct hashentry_s *prev, *next;
|
||||
};
|
||||
|
||||
struct hashbucket_s
|
||||
{
|
||||
struct hashbucket_s {
|
||||
struct hashentry_s *head, *tail;
|
||||
};
|
||||
|
||||
struct hashmap_s
|
||||
{
|
||||
struct hashmap_s {
|
||||
unsigned int size;
|
||||
hashmap_iter end_iterator;
|
||||
|
||||
@ -68,8 +65,7 @@ struct hashmap_s
|
||||
*
|
||||
* If any of the arguments are invalid a negative number is returned.
|
||||
*/
|
||||
static int
|
||||
hashfunc (const char *key, unsigned int size)
|
||||
static int hashfunc (const char *key, unsigned int size)
|
||||
{
|
||||
uint32_t hash;
|
||||
|
||||
@ -78,8 +74,7 @@ hashfunc (const char *key, unsigned int size)
|
||||
if (size == 0)
|
||||
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;
|
||||
|
||||
hash >>= 1;
|
||||
@ -98,23 +93,22 @@ hashfunc (const char *key, unsigned int size)
|
||||
*
|
||||
* NULLs are also returned if memory could not be allocated for hashmap.
|
||||
*/
|
||||
hashmap_t
|
||||
hashmap_create (unsigned int nbuckets)
|
||||
hashmap_t hashmap_create (unsigned int nbuckets)
|
||||
{
|
||||
struct hashmap_s *ptr;
|
||||
|
||||
if (nbuckets == 0)
|
||||
return NULL;
|
||||
|
||||
ptr = (struct hashmap_s *)safecalloc (1, sizeof (struct hashmap_s));
|
||||
ptr = (struct hashmap_s *) safecalloc (1, sizeof (struct hashmap_s));
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
|
||||
ptr->size = nbuckets;
|
||||
ptr->buckets = (struct hashbucket_s *)safecalloc (nbuckets,
|
||||
sizeof (struct hashbucket_s));
|
||||
if (!ptr->buckets)
|
||||
{
|
||||
ptr->buckets = (struct hashbucket_s *) safecalloc (nbuckets,
|
||||
sizeof (struct
|
||||
hashbucket_s));
|
||||
if (!ptr->buckets) {
|
||||
safefree (ptr);
|
||||
return NULL;
|
||||
}
|
||||
@ -132,8 +126,7 @@ hashmap_create (unsigned int nbuckets)
|
||||
* Returns: 0 if the function completed successfully
|
||||
* negative number is returned if "entry" was NULL
|
||||
*/
|
||||
static inline int
|
||||
delete_hashbucket (struct hashbucket_s *bucket)
|
||||
static inline int delete_hashbucket (struct hashbucket_s *bucket)
|
||||
{
|
||||
struct hashentry_s *nextptr;
|
||||
struct hashentry_s *ptr;
|
||||
@ -142,8 +135,7 @@ delete_hashbucket (struct hashbucket_s *bucket)
|
||||
return -EINVAL;
|
||||
|
||||
ptr = bucket->head;
|
||||
while (ptr)
|
||||
{
|
||||
while (ptr) {
|
||||
nextptr = ptr->next;
|
||||
|
||||
safefree (ptr->key);
|
||||
@ -162,18 +154,15 @@ delete_hashbucket (struct hashbucket_s *bucket)
|
||||
* Returns: 0 on success
|
||||
* negative if a NULL "map" was supplied
|
||||
*/
|
||||
int
|
||||
hashmap_delete (hashmap_t map)
|
||||
int hashmap_delete (hashmap_t map)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (map == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i != map->size; i++)
|
||||
{
|
||||
if (map->buckets[i].head != NULL)
|
||||
{
|
||||
for (i = 0; i != map->size; i++) {
|
||||
if (map->buckets[i].head != NULL) {
|
||||
delete_hashbucket (&map->buckets[i]);
|
||||
}
|
||||
}
|
||||
@ -225,16 +214,14 @@ hashmap_insert (hashmap_t map, const char *key, const void *data, size_t len)
|
||||
return -ENOMEM;
|
||||
|
||||
data_copy = safemalloc (len);
|
||||
if (!data_copy)
|
||||
{
|
||||
if (!data_copy) {
|
||||
safefree (key_copy);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy (data_copy, data, len);
|
||||
|
||||
ptr = (struct hashentry_s *)safemalloc (sizeof (struct hashentry_s));
|
||||
if (!ptr)
|
||||
{
|
||||
ptr = (struct hashentry_s *) safemalloc (sizeof (struct hashentry_s));
|
||||
if (!ptr) {
|
||||
safefree (key_copy);
|
||||
safefree (data_copy);
|
||||
return -ENOMEM;
|
||||
@ -265,8 +252,7 @@ hashmap_insert (hashmap_t map, const char *key, const void *data, size_t len)
|
||||
*
|
||||
* Returns: an negative value upon error.
|
||||
*/
|
||||
hashmap_iter
|
||||
hashmap_first (hashmap_t map)
|
||||
hashmap_iter hashmap_first (hashmap_t map)
|
||||
{
|
||||
assert (map != NULL);
|
||||
|
||||
@ -285,8 +271,7 @@ hashmap_first (hashmap_t map)
|
||||
* Returns: 1 if it is the end
|
||||
* 0 otherwise
|
||||
*/
|
||||
int
|
||||
hashmap_is_end (hashmap_t map, hashmap_iter iter)
|
||||
int hashmap_is_end (hashmap_t map, hashmap_iter iter)
|
||||
{
|
||||
assert (map != NULL);
|
||||
assert (iter >= 0);
|
||||
@ -308,8 +293,7 @@ hashmap_is_end (hashmap_t map, hashmap_iter iter)
|
||||
* an "iterator" pointing at the first key
|
||||
* an "end-iterator" if the key wasn't found
|
||||
*/
|
||||
hashmap_iter
|
||||
hashmap_find (hashmap_t map, const char *key)
|
||||
hashmap_iter hashmap_find (hashmap_t map, const char *key)
|
||||
{
|
||||
unsigned int i;
|
||||
hashmap_iter iter = 0;
|
||||
@ -325,14 +309,11 @@ hashmap_find (hashmap_t map, const char *key)
|
||||
* Loop through all the keys and look for the first occurrence
|
||||
* of a particular key.
|
||||
*/
|
||||
for (i = 0; i != map->size; i++)
|
||||
{
|
||||
for (i = 0; i != map->size; i++) {
|
||||
ptr = map->buckets[i].head;
|
||||
|
||||
while (ptr)
|
||||
{
|
||||
if (strcasecmp (ptr->key, key) == 0)
|
||||
{
|
||||
while (ptr) {
|
||||
if (strcasecmp (ptr->key, key) == 0) {
|
||||
/* Found it, so return the current count */
|
||||
return iter;
|
||||
}
|
||||
@ -352,8 +333,7 @@ hashmap_find (hashmap_t map, const char *key)
|
||||
* negative upon error
|
||||
*/
|
||||
ssize_t
|
||||
hashmap_return_entry (hashmap_t map, hashmap_iter iter, char **key,
|
||||
void **data)
|
||||
hashmap_return_entry (hashmap_t map, hashmap_iter iter, char **key, void **data)
|
||||
{
|
||||
unsigned int i;
|
||||
struct hashentry_s *ptr;
|
||||
@ -368,13 +348,10 @@ hashmap_return_entry (hashmap_t map, hashmap_iter iter, char **key,
|
||||
if (!map || iter < 0 || !key || !data)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i != map->size; i++)
|
||||
{
|
||||
for (i = 0; i != map->size; i++) {
|
||||
ptr = map->buckets[i].head;
|
||||
while (ptr)
|
||||
{
|
||||
if (count == iter)
|
||||
{
|
||||
while (ptr) {
|
||||
if (count == iter) {
|
||||
/* This is the data so return it */
|
||||
*key = ptr->key;
|
||||
*data = ptr->data;
|
||||
@ -396,8 +373,7 @@ hashmap_return_entry (hashmap_t map, hashmap_iter iter, char **key,
|
||||
* zero if no key is found
|
||||
* count found
|
||||
*/
|
||||
ssize_t
|
||||
hashmap_search (hashmap_t map, const char *key)
|
||||
ssize_t hashmap_search (hashmap_t map, const char *key)
|
||||
{
|
||||
int hash;
|
||||
struct hashentry_s *ptr;
|
||||
@ -413,8 +389,7 @@ hashmap_search (hashmap_t map, const char *key)
|
||||
ptr = map->buckets[hash].head;
|
||||
|
||||
/* 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)
|
||||
++count;
|
||||
|
||||
@ -433,8 +408,7 @@ hashmap_search (hashmap_t map, const char *key)
|
||||
* zero if no entry is found
|
||||
* length of data for the entry
|
||||
*/
|
||||
ssize_t
|
||||
hashmap_entry_by_key (hashmap_t map, const char *key, void **data)
|
||||
ssize_t hashmap_entry_by_key (hashmap_t map, const char *key, void **data)
|
||||
{
|
||||
int hash;
|
||||
struct hashentry_s *ptr;
|
||||
@ -448,10 +422,8 @@ hashmap_entry_by_key (hashmap_t map, const char *key, void **data)
|
||||
|
||||
ptr = map->buckets[hash].head;
|
||||
|
||||
while (ptr)
|
||||
{
|
||||
if (strcasecmp (ptr->key, key) == 0)
|
||||
{
|
||||
while (ptr) {
|
||||
if (strcasecmp (ptr->key, key) == 0) {
|
||||
*data = ptr->data;
|
||||
return ptr->len;
|
||||
}
|
||||
@ -470,8 +442,7 @@ hashmap_entry_by_key (hashmap_t map, const char *key, void **data)
|
||||
* 0 if the key was not found
|
||||
* positive count of entries deleted
|
||||
*/
|
||||
ssize_t
|
||||
hashmap_remove (hashmap_t map, const char *key)
|
||||
ssize_t hashmap_remove (hashmap_t map, const char *key)
|
||||
{
|
||||
int hash;
|
||||
struct hashentry_s *ptr, *next;
|
||||
@ -485,10 +456,8 @@ hashmap_remove (hashmap_t map, const char *key)
|
||||
return hash;
|
||||
|
||||
ptr = map->buckets[hash].head;
|
||||
while (ptr)
|
||||
{
|
||||
if (strcasecmp (ptr->key, key) == 0)
|
||||
{
|
||||
while (ptr) {
|
||||
if (strcasecmp (ptr->key, key) == 0) {
|
||||
/*
|
||||
* Found the data, now need to remove everything
|
||||
* and update the hashmap.
|
||||
|
@ -26,15 +26,15 @@
|
||||
* hash map. Sure, it's a pointer, but the struct is hidden in the C file.
|
||||
* So, just use the hashmap_t like it's a cookie. :)
|
||||
*/
|
||||
typedef struct hashmap_s *hashmap_t;
|
||||
typedef int hashmap_iter;
|
||||
typedef struct hashmap_s *hashmap_t;
|
||||
typedef int hashmap_iter;
|
||||
|
||||
/*
|
||||
* hashmap_create() takes one argument, which is the number of buckets to
|
||||
* use internally. hashmap_delete() is self explanatory.
|
||||
*/
|
||||
extern hashmap_t hashmap_create (unsigned int nbuckets);
|
||||
extern int hashmap_delete (hashmap_t map);
|
||||
extern hashmap_t hashmap_create (unsigned int nbuckets);
|
||||
extern int hashmap_delete (hashmap_t map);
|
||||
|
||||
/*
|
||||
* When the you insert a key/data pair into the hashmap it will the key
|
||||
@ -45,7 +45,7 @@
|
||||
* Returns: negative on error
|
||||
* 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);
|
||||
|
||||
/*
|
||||
@ -53,7 +53,7 @@
|
||||
*
|
||||
* 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.
|
||||
@ -61,7 +61,7 @@
|
||||
* Returns: 1 if it is the end
|
||||
* 0 otherwise
|
||||
*/
|
||||
extern int hashmap_is_end (hashmap_t map, hashmap_iter iter);
|
||||
extern int hashmap_is_end (hashmap_t map, hashmap_iter iter);
|
||||
|
||||
/*
|
||||
* Return a "pointer" to the first instance of the particular key. It can
|
||||
@ -71,7 +71,7 @@
|
||||
* an "iterator" pointing at the first key
|
||||
* an "end-iterator" if the key wasn't found
|
||||
*/
|
||||
extern hashmap_iter hashmap_find (hashmap_t map, const char *key);
|
||||
extern hashmap_iter hashmap_find (hashmap_t map, const char *key);
|
||||
|
||||
/*
|
||||
* Retrieve the key/data associated with a particular iterator.
|
||||
@ -81,7 +81,7 @@
|
||||
* Returns: the length of the data block upon success
|
||||
* 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);
|
||||
|
||||
/*
|
||||
@ -92,7 +92,7 @@
|
||||
* zero if no entry is found
|
||||
* length of data for the entry
|
||||
*/
|
||||
extern ssize_t hashmap_entry_by_key (hashmap_t map, const char *key,
|
||||
extern ssize_t hashmap_entry_by_key (hashmap_t map, const char *key,
|
||||
void **data);
|
||||
|
||||
/*
|
||||
@ -103,7 +103,7 @@
|
||||
* zero if no key is found
|
||||
* count found (positive value)
|
||||
*/
|
||||
extern ssize_t hashmap_search (hashmap_t map, const char *key);
|
||||
extern ssize_t hashmap_search (hashmap_t map, const char *key);
|
||||
|
||||
/*
|
||||
* Go through the hashmap and remove the particular key.
|
||||
@ -113,6 +113,6 @@
|
||||
* 0 if the key was not found
|
||||
* positive count of entries deleted
|
||||
*/
|
||||
extern ssize_t hashmap_remove (hashmap_t map, const char *key);
|
||||
extern ssize_t hashmap_remove (hashmap_t map, const char *key);
|
||||
|
||||
#endif /* _HASHMAP_H */
|
||||
|
27
src/heap.c
27
src/heap.c
@ -27,8 +27,7 @@
|
||||
#include "heap.h"
|
||||
#include "text.h"
|
||||
|
||||
void *
|
||||
debugging_calloc (size_t nmemb, size_t size, const char *file,
|
||||
void *debugging_calloc (size_t nmemb, size_t size, const char *file,
|
||||
unsigned long line)
|
||||
{
|
||||
void *ptr;
|
||||
@ -37,13 +36,12 @@ debugging_calloc (size_t nmemb, size_t size, const char *file,
|
||||
assert (size > 0);
|
||||
|
||||
ptr = calloc (nmemb, size);
|
||||
fprintf (stderr, "{calloc: %p:%zu x %zu} %s:%lu\n", ptr, nmemb, size, file,
|
||||
line);
|
||||
fprintf (stderr, "{calloc: %p:%zu x %zu} %s:%lu\n", ptr, nmemb, size,
|
||||
file, line);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *
|
||||
debugging_malloc (size_t size, const char *file, unsigned long line)
|
||||
void *debugging_malloc (size_t size, const char *file, unsigned long line)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
@ -54,8 +52,7 @@ debugging_malloc (size_t size, const char *file, unsigned long line)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *
|
||||
debugging_realloc (void *ptr, size_t size, const char *file,
|
||||
void *debugging_realloc (void *ptr, size_t size, const char *file,
|
||||
unsigned long line)
|
||||
{
|
||||
void *newptr;
|
||||
@ -68,8 +65,7 @@ debugging_realloc (void *ptr, size_t size, const char *file,
|
||||
return newptr;
|
||||
}
|
||||
|
||||
void
|
||||
debugging_free (void *ptr, const char *file, unsigned long line)
|
||||
void debugging_free (void *ptr, const char *file, unsigned long line)
|
||||
{
|
||||
fprintf (stderr, "{free: %p} %s:%lu\n", ptr, file, line);
|
||||
|
||||
@ -78,8 +74,7 @@ debugging_free (void *ptr, const char *file, unsigned long line)
|
||||
return;
|
||||
}
|
||||
|
||||
char *
|
||||
debugging_strdup (const char *s, const char *file, unsigned long line)
|
||||
char *debugging_strdup (const char *s, const char *file, unsigned long line)
|
||||
{
|
||||
char *ptr;
|
||||
size_t len;
|
||||
@ -87,7 +82,7 @@ debugging_strdup (const char *s, const char *file, unsigned long line)
|
||||
assert (s != NULL);
|
||||
|
||||
len = strlen (s) + 1;
|
||||
ptr = (char *)malloc (len);
|
||||
ptr = (char *) malloc (len);
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
memcpy (ptr, s, len);
|
||||
@ -104,8 +99,7 @@ debugging_strdup (const char *s, const char *file, unsigned long line)
|
||||
* want to look into something like MM (Shared Memory Library) for a better
|
||||
* solution.
|
||||
*/
|
||||
void *
|
||||
malloc_shared_memory (size_t size)
|
||||
void *malloc_shared_memory (size_t size)
|
||||
{
|
||||
int fd;
|
||||
void *ptr;
|
||||
@ -137,8 +131,7 @@ malloc_shared_memory (size_t size)
|
||||
* Allocate a block of memory from the "shared" region an initialize it to
|
||||
* zero.
|
||||
*/
|
||||
void *
|
||||
calloc_shared_memory (size_t nmemb, size_t size)
|
||||
void *calloc_shared_memory (size_t nmemb, size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
long length;
|
||||
|
@ -36,8 +36,7 @@
|
||||
#define ERRORNUM_BUFSIZE 8 /* this is more than required */
|
||||
#define ERRPAGES_BUCKETCOUNT 16
|
||||
|
||||
int
|
||||
add_new_errorpage (char *filepath, unsigned int errornum)
|
||||
int add_new_errorpage (char *filepath, unsigned int errornum)
|
||||
{
|
||||
char errornbuf[ERRORNUM_BUFSIZE];
|
||||
|
||||
@ -57,8 +56,7 @@ add_new_errorpage (char *filepath, unsigned int errornum)
|
||||
/*
|
||||
* Get the file appropriate for a given error.
|
||||
*/
|
||||
static char *
|
||||
get_html_file (unsigned int errornum)
|
||||
static char *get_html_file (unsigned int errornum)
|
||||
{
|
||||
hashmap_iter result_iter;
|
||||
char errornbuf[ERRORNUM_BUFSIZE];
|
||||
@ -87,8 +85,7 @@ get_html_file (unsigned int errornum)
|
||||
/*
|
||||
* Look up the value for a variable.
|
||||
*/
|
||||
static char *
|
||||
lookup_variable (struct conn_s *connptr, const char *varname)
|
||||
static char *lookup_variable (struct conn_s *connptr, const char *varname)
|
||||
{
|
||||
hashmap_iter result_iter;
|
||||
char *key;
|
||||
@ -111,34 +108,33 @@ lookup_variable (struct conn_s *connptr, const char *varname)
|
||||
/*
|
||||
* Send an already-opened file to the client with variable substitution.
|
||||
*/
|
||||
int
|
||||
send_html_file (FILE * infile, struct conn_s *connptr)
|
||||
int send_html_file (FILE * infile, struct conn_s *connptr)
|
||||
{
|
||||
char inbuf[HTML_BUFSIZE], *varstart = NULL, *p;
|
||||
const char *varval;
|
||||
int in_variable = 0, writeret;
|
||||
|
||||
while (fgets (inbuf, HTML_BUFSIZE, infile) != NULL)
|
||||
{
|
||||
for (p = inbuf; *p; p++)
|
||||
{
|
||||
switch (*p)
|
||||
{
|
||||
while (fgets (inbuf, HTML_BUFSIZE, infile) != NULL) {
|
||||
for (p = inbuf; *p; p++) {
|
||||
switch (*p) {
|
||||
case '}':
|
||||
if (in_variable)
|
||||
{
|
||||
if (in_variable) {
|
||||
*p = '\0';
|
||||
varval = (const char *)lookup_variable (connptr, varstart);
|
||||
varval =
|
||||
(const char *)
|
||||
lookup_variable (connptr, varstart);
|
||||
if (!varval)
|
||||
varval = "(unknown)";
|
||||
writeret = write_message (connptr->client_fd, "%s", varval);
|
||||
writeret =
|
||||
write_message (connptr->client_fd,
|
||||
"%s", varval);
|
||||
if (writeret)
|
||||
return (writeret);
|
||||
in_variable = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
writeret = write_message (connptr->client_fd, "%c", *p);
|
||||
} else {
|
||||
writeret =
|
||||
write_message (connptr->client_fd,
|
||||
"%c", *p);
|
||||
if (writeret)
|
||||
return (writeret);
|
||||
}
|
||||
@ -150,17 +146,16 @@ send_html_file (FILE * infile, struct conn_s *connptr)
|
||||
* this code will fallthrough to the code that
|
||||
* just dumps a character to the client fd.
|
||||
*/
|
||||
if (!in_variable)
|
||||
{
|
||||
if (!in_variable) {
|
||||
varstart = p + 1;
|
||||
in_variable++;
|
||||
}
|
||||
else
|
||||
} else
|
||||
in_variable = 0;
|
||||
default:
|
||||
if (!in_variable)
|
||||
{
|
||||
writeret = write_message (connptr->client_fd, "%c", *p);
|
||||
if (!in_variable) {
|
||||
writeret =
|
||||
write_message (connptr->client_fd,
|
||||
"%c", *p);
|
||||
if (writeret)
|
||||
return (writeret);
|
||||
}
|
||||
@ -172,8 +167,7 @@ send_html_file (FILE * infile, struct conn_s *connptr)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
send_http_headers (struct conn_s *connptr, int code, const char *message)
|
||||
int send_http_headers (struct conn_s *connptr, int code, const char *message)
|
||||
{
|
||||
const char *headers =
|
||||
"HTTP/1.0 %d %s\r\n"
|
||||
@ -187,8 +181,7 @@ send_http_headers (struct conn_s *connptr, int code, const char *message)
|
||||
/*
|
||||
* Display an error to the client.
|
||||
*/
|
||||
int
|
||||
send_http_error_message (struct conn_s *connptr)
|
||||
int send_http_error_message (struct conn_s *connptr)
|
||||
{
|
||||
char *error_file;
|
||||
FILE *infile;
|
||||
@ -203,13 +196,14 @@ send_http_error_message (struct conn_s *connptr)
|
||||
"<h1>%s</h1>\n"
|
||||
"<p>%s</p>\n"
|
||||
"<hr />\n"
|
||||
"<p><em>Generated by %s version %s.</em></p>\n" "</body>\n" "</html>\n";
|
||||
"<p><em>Generated by %s version %s.</em></p>\n" "</body>\n"
|
||||
"</html>\n";
|
||||
|
||||
send_http_headers (connptr, connptr->error_number, connptr->error_string);
|
||||
send_http_headers (connptr, connptr->error_number,
|
||||
connptr->error_string);
|
||||
|
||||
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,
|
||||
connptr->error_number,
|
||||
@ -233,7 +227,9 @@ int
|
||||
add_error_variable (struct conn_s *connptr, const char *key, const char *val)
|
||||
{
|
||||
if (!connptr->error_variables)
|
||||
if (!(connptr->error_variables = hashmap_create (ERRVAR_BUCKETCOUNT)))
|
||||
if (!
|
||||
(connptr->error_variables =
|
||||
hashmap_create (ERRVAR_BUCKETCOUNT)))
|
||||
return (-1);
|
||||
|
||||
return hashmap_insert (connptr->error_variables, key, val,
|
||||
@ -251,8 +247,7 @@ add_error_variable (struct conn_s *connptr, const char *key, const char *val)
|
||||
/*
|
||||
* Set some standard variables used by all HTML pages
|
||||
*/
|
||||
int
|
||||
add_standard_vars (struct conn_s *connptr)
|
||||
int add_standard_vars (struct conn_s *connptr)
|
||||
{
|
||||
char errnobuf[16];
|
||||
char timebuf[30];
|
||||
@ -276,7 +271,8 @@ add_standard_vars (struct conn_s *connptr)
|
||||
gmtime (&global_time));
|
||||
add_error_variable (connptr, "date", timebuf);
|
||||
|
||||
add_error_variable (connptr, "website", "http://www.banu.com/tinyproxy/");
|
||||
add_error_variable (connptr, "website",
|
||||
"http://www.banu.com/tinyproxy/");
|
||||
add_error_variable (connptr, "version", VERSION);
|
||||
add_error_variable (connptr, "package", PACKAGE);
|
||||
|
||||
@ -295,12 +291,10 @@ indicate_http_error (struct conn_s *connptr, int number,
|
||||
|
||||
va_start (ap, message);
|
||||
|
||||
while ((key = va_arg (ap, char *)))
|
||||
{
|
||||
while ((key = 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);
|
||||
return (-1);
|
||||
}
|
||||
|
@ -30,11 +30,9 @@
|
||||
* Also, the caller MUST NOT free the memory while the structure is
|
||||
* 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 */
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
const char *string;
|
||||
int code;
|
||||
} response;
|
||||
@ -44,16 +42,14 @@ struct http_message_s
|
||||
* the strings are referenced through pointers in an array.
|
||||
* I might change this to a vector in the future.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
const char **strings;
|
||||
unsigned int total;
|
||||
unsigned int used;
|
||||
} headers;
|
||||
|
||||
/* Body of the message (most likely an HTML message) */
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
const char *text;
|
||||
size_t length;
|
||||
} body;
|
||||
@ -64,8 +60,7 @@ struct http_message_s
|
||||
* function. It returns 0 if the message is invalid; otherwise, a positive
|
||||
* number is returned. Useful for if() tests and assert() tests.
|
||||
*/
|
||||
static int
|
||||
is_http_message_valid (http_message_t msg)
|
||||
static int is_http_message_valid (http_message_t msg)
|
||||
{
|
||||
if (msg == NULL)
|
||||
return 0;
|
||||
@ -92,14 +87,16 @@ http_message_create (int response_code, const char *response_string)
|
||||
http_message_t msg;
|
||||
int ret;
|
||||
|
||||
msg = (struct http_message_s *)safecalloc (1, sizeof (struct http_message_s));
|
||||
msg =
|
||||
(struct http_message_s *) safecalloc (1,
|
||||
sizeof (struct
|
||||
http_message_s));
|
||||
if (msg == NULL)
|
||||
return NULL;
|
||||
|
||||
msg->headers.strings = (const char **)safecalloc (NUMBER_OF_HEADERS,
|
||||
msg->headers.strings = (const char **) safecalloc (NUMBER_OF_HEADERS,
|
||||
sizeof (char *));
|
||||
if (msg->headers.strings == NULL)
|
||||
{
|
||||
if (msg->headers.strings == NULL) {
|
||||
safefree (msg);
|
||||
return NULL;
|
||||
}
|
||||
@ -108,8 +105,7 @@ http_message_create (int response_code, const char *response_string)
|
||||
|
||||
/* Store the HTTP response information in the structure */
|
||||
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);
|
||||
return NULL;
|
||||
@ -123,8 +119,7 @@ http_message_create (int response_code, const char *response_string)
|
||||
* This DOES NOT free the pointers stored in this structure. That memory
|
||||
* is the responsibility of the caller.
|
||||
*/
|
||||
int
|
||||
http_message_destroy (http_message_t msg)
|
||||
int http_message_destroy (http_message_t msg)
|
||||
{
|
||||
assert (msg != NULL);
|
||||
assert (msg->headers.strings != NULL);
|
||||
@ -166,8 +161,7 @@ http_message_set_response (http_message_t msg,
|
||||
/*
|
||||
* Set the HTTP message body.
|
||||
*/
|
||||
int
|
||||
http_message_set_body (http_message_t msg, const char *body, size_t len)
|
||||
int http_message_set_body (http_message_t msg, const char *body, size_t len)
|
||||
{
|
||||
/* Check for valid arguments */
|
||||
if (msg == NULL)
|
||||
@ -203,9 +197,9 @@ http_message_add_headers (http_message_t msg, const char **headers,
|
||||
* If the number of headers to add is greater than the space
|
||||
* available, reallocate the memory.
|
||||
*/
|
||||
if (msg->headers.used + num_headers > msg->headers.total)
|
||||
{
|
||||
new_headers = (const char **)safecalloc (msg->headers.total * 2,
|
||||
if (msg->headers.used + num_headers > msg->headers.total) {
|
||||
new_headers =
|
||||
(const char **) safecalloc (msg->headers.total * 2,
|
||||
sizeof (char *));
|
||||
if (new_headers == NULL)
|
||||
return -ENOMEM;
|
||||
@ -233,8 +227,7 @@ http_message_add_headers (http_message_t msg, const char **headers,
|
||||
/*
|
||||
* Send the completed HTTP message via the supplied file descriptor.
|
||||
*/
|
||||
int
|
||||
http_message_send (http_message_t msg, int fd)
|
||||
int http_message_send (http_message_t msg, int fd)
|
||||
{
|
||||
char timebuf[30];
|
||||
time_t global_time;
|
||||
|
58
src/log.c
58
src/log.c
@ -64,8 +64,7 @@ static vector_t log_message_storage;
|
||||
/*
|
||||
* Open the log file and store the file descriptor in a global location.
|
||||
*/
|
||||
int
|
||||
open_log_file (const char *log_file_name)
|
||||
int open_log_file (const char *log_file_name)
|
||||
{
|
||||
log_file_fd = create_file_safely (log_file_name, FALSE);
|
||||
return log_file_fd;
|
||||
@ -74,8 +73,7 @@ open_log_file (const char *log_file_name)
|
||||
/*
|
||||
* Close the log file
|
||||
*/
|
||||
void
|
||||
close_log_file (void)
|
||||
void close_log_file (void)
|
||||
{
|
||||
close (log_file_fd);
|
||||
}
|
||||
@ -83,8 +81,7 @@ close_log_file (void)
|
||||
/*
|
||||
* Truncate log file to a zero length.
|
||||
*/
|
||||
void
|
||||
truncate_log_file (void)
|
||||
void truncate_log_file (void)
|
||||
{
|
||||
lseek (log_file_fd, 0, SEEK_SET);
|
||||
ftruncate (log_file_fd, 0);
|
||||
@ -93,8 +90,7 @@ truncate_log_file (void)
|
||||
/*
|
||||
* Set the log level for writing to the log file.
|
||||
*/
|
||||
void
|
||||
set_log_level (int level)
|
||||
void set_log_level (int level)
|
||||
{
|
||||
log_level = level;
|
||||
}
|
||||
@ -102,8 +98,7 @@ set_log_level (int level)
|
||||
/*
|
||||
* This routine logs messages to either the log file or the syslog function.
|
||||
*/
|
||||
void
|
||||
log_message (int level, const char *fmt, ...)
|
||||
void log_message (int level, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
time_t nowtime;
|
||||
@ -115,17 +110,13 @@ log_message (int level, const char *fmt, ...)
|
||||
/*
|
||||
* Figure out if we should write the message or not.
|
||||
*/
|
||||
if (log_level == LOG_CONN)
|
||||
{
|
||||
if (log_level == LOG_CONN) {
|
||||
if (level == LOG_INFO)
|
||||
return;
|
||||
}
|
||||
else if (log_level == LOG_INFO)
|
||||
{
|
||||
} else if (log_level == LOG_INFO) {
|
||||
if (level > LOG_INFO && level != LOG_CONN)
|
||||
return;
|
||||
}
|
||||
else if (level > log_level)
|
||||
} else if (level > log_level)
|
||||
return;
|
||||
#endif
|
||||
|
||||
@ -140,12 +131,10 @@ log_message (int level, const char *fmt, ...)
|
||||
* If the config file hasn't been processed, then we need to store
|
||||
* the messages for later processing.
|
||||
*/
|
||||
if (!processed_config_file)
|
||||
{
|
||||
if (!processed_config_file) {
|
||||
char *entry_buffer;
|
||||
|
||||
if (!log_message_storage)
|
||||
{
|
||||
if (!log_message_storage) {
|
||||
log_message_storage = vector_create ();
|
||||
if (!log_message_storage)
|
||||
goto out;
|
||||
@ -153,7 +142,7 @@ log_message (int level, const char *fmt, ...)
|
||||
|
||||
vsnprintf (str, STRING_LENGTH, fmt, args);
|
||||
|
||||
entry_buffer = (char *)safemalloc (strlen (str) + 6);
|
||||
entry_buffer = (char *) safemalloc (strlen (str) + 6);
|
||||
if (!entry_buffer)
|
||||
goto out;
|
||||
|
||||
@ -165,17 +154,14 @@ log_message (int level, const char *fmt, ...)
|
||||
goto out;
|
||||
}
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
if (config.syslog)
|
||||
{
|
||||
if (config.syslog) {
|
||||
# ifdef HAVE_VSYSLOG_H
|
||||
vsyslog (level, fmt, args);
|
||||
# else
|
||||
vsnprintf (str, STRING_LENGTH, fmt, args);
|
||||
syslog (level, "%s", str);
|
||||
# endif
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
#endif
|
||||
nowtime = time (NULL);
|
||||
/* Format is month day hour:minute:second (24 time) */
|
||||
@ -183,7 +169,8 @@ log_message (int level, const char *fmt, ...)
|
||||
localtime (&nowtime));
|
||||
|
||||
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);
|
||||
|
||||
@ -204,8 +191,7 @@ out:
|
||||
/*
|
||||
* This needs to send any stored log messages.
|
||||
*/
|
||||
void
|
||||
send_stored_logs (void)
|
||||
void send_stored_logs (void)
|
||||
{
|
||||
char *string;
|
||||
char *ptr;
|
||||
@ -214,9 +200,9 @@ send_stored_logs (void)
|
||||
|
||||
size_t i;
|
||||
|
||||
for (i = 0; (ssize_t)i != vector_length (log_message_storage); ++i)
|
||||
{
|
||||
string = (char *)vector_getentry (log_message_storage, i, NULL);
|
||||
for (i = 0; (ssize_t) i != vector_length (log_message_storage); ++i) {
|
||||
string =
|
||||
(char *) vector_getentry (log_message_storage, i, NULL);
|
||||
|
||||
ptr = strchr (string, ' ') + 1;
|
||||
level = atoi (string);
|
||||
@ -224,12 +210,10 @@ send_stored_logs (void)
|
||||
#ifdef NDEBUG
|
||||
if (log_level == LOG_CONN && level == LOG_INFO)
|
||||
continue;
|
||||
else if (log_level == LOG_INFO)
|
||||
{
|
||||
else if (log_level == LOG_INFO) {
|
||||
if (level > LOG_INFO && level != LOG_CONN)
|
||||
continue;
|
||||
}
|
||||
else if (level > log_level)
|
||||
} else if (level > log_level)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
|
162
src/main.c
162
src/main.c
@ -54,14 +54,12 @@ unsigned int processed_config_file = FALSE; /* boolean */
|
||||
/*
|
||||
* Handle a signal
|
||||
*/
|
||||
RETSIGTYPE
|
||||
takesig (int sig)
|
||||
RETSIGTYPE takesig (int sig)
|
||||
{
|
||||
pid_t pid;
|
||||
int status;
|
||||
|
||||
switch (sig)
|
||||
{
|
||||
switch (sig) {
|
||||
case SIGHUP:
|
||||
received_sighup = TRUE;
|
||||
break;
|
||||
@ -71,7 +69,7 @@ takesig (int sig)
|
||||
break;
|
||||
|
||||
case SIGCHLD:
|
||||
while ((pid = waitpid (-1, &status, WNOHANG)) > 0);
|
||||
while ((pid = waitpid (-1, &status, WNOHANG)) > 0) ;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -81,8 +79,7 @@ takesig (int sig)
|
||||
/*
|
||||
* Display the version information for the user.
|
||||
*/
|
||||
static void
|
||||
display_version (void)
|
||||
static void display_version (void)
|
||||
{
|
||||
printf ("%s %s (%s)\n", PACKAGE, VERSION, TARGET_SYSTEM);
|
||||
}
|
||||
@ -90,8 +87,7 @@ display_version (void)
|
||||
/*
|
||||
* Display the copyright and license for this program.
|
||||
*/
|
||||
static void
|
||||
display_license (void)
|
||||
static void display_license (void)
|
||||
{
|
||||
display_version ();
|
||||
|
||||
@ -119,8 +115,7 @@ display_license (void)
|
||||
/*
|
||||
* Display usage to the user.
|
||||
*/
|
||||
static void
|
||||
display_usage (void)
|
||||
static void display_usage (void)
|
||||
{
|
||||
printf ("Usage: %s [options]\n", PACKAGE);
|
||||
printf ("\
|
||||
@ -150,8 +145,7 @@ Options:\n\
|
||||
#endif /* REVERSE_SUPPORT */
|
||||
}
|
||||
|
||||
static int
|
||||
get_id (char *str)
|
||||
static int get_id (char *str)
|
||||
{
|
||||
char *tstr;
|
||||
|
||||
@ -159,8 +153,7 @@ get_id (char *str)
|
||||
return -1;
|
||||
|
||||
tstr = str;
|
||||
while (*tstr != 0)
|
||||
{
|
||||
while (*tstr != 0) {
|
||||
if (!isdigit (*tstr))
|
||||
return -1;
|
||||
tstr++;
|
||||
@ -169,8 +162,7 @@ get_id (char *str)
|
||||
return atoi (str);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int optch;
|
||||
unsigned int godaemon = TRUE; /* boolean */
|
||||
@ -189,10 +181,8 @@ main (int argc, char **argv)
|
||||
/*
|
||||
* Process the various options
|
||||
*/
|
||||
while ((optch = getopt (argc, argv, "c:vldh")) != EOF)
|
||||
{
|
||||
switch (optch)
|
||||
{
|
||||
while ((optch = getopt (argc, argv, "c:vldh")) != EOF) {
|
||||
switch (optch) {
|
||||
case 'v':
|
||||
display_version ();
|
||||
exit (EX_OK);
|
||||
@ -204,9 +194,10 @@ main (int argc, char **argv)
|
||||
break;
|
||||
case 'c':
|
||||
config.config_file = safestrdup (optarg);
|
||||
if (!config.config_file)
|
||||
{
|
||||
fprintf (stderr, "%s: Could not allocate memory.\n", argv[0]);
|
||||
if (!config.config_file) {
|
||||
fprintf (stderr,
|
||||
"%s: Could not allocate memory.\n",
|
||||
argv[0]);
|
||||
exit (EX_SOFTWARE);
|
||||
}
|
||||
break;
|
||||
@ -229,15 +220,13 @@ main (int argc, char **argv)
|
||||
* Read in the settings from the config file.
|
||||
*/
|
||||
config_file = fopen (config.config_file, "r");
|
||||
if (!config_file)
|
||||
{
|
||||
if (!config_file) {
|
||||
fprintf (stderr,
|
||||
"%s: Could not open configuration file \"%s\".\n",
|
||||
argv[0], config.config_file);
|
||||
exit (EX_SOFTWARE);
|
||||
}
|
||||
if (config_compile () || config_parse (&config, config_file))
|
||||
{
|
||||
if (config_compile () || config_parse (&config, config_file)) {
|
||||
fprintf (stderr,
|
||||
"Unable to parse configuration file. Not starting.\n");
|
||||
exit (EX_SOFTWARE);
|
||||
@ -248,24 +237,19 @@ main (int argc, char **argv)
|
||||
* Write to a user supplied log file if it's defined. This
|
||||
* will override using the syslog even if syslog is defined.
|
||||
*/
|
||||
if (config.logf_name)
|
||||
{
|
||||
if (open_log_file (config.logf_name) < 0)
|
||||
{
|
||||
fprintf (stderr, "%s: Could not create log file.\n", argv[0]);
|
||||
if (config.logf_name) {
|
||||
if (open_log_file (config.logf_name) < 0) {
|
||||
fprintf (stderr, "%s: Could not create log file.\n",
|
||||
argv[0]);
|
||||
exit (EX_SOFTWARE);
|
||||
}
|
||||
config.syslog = FALSE; /* disable syslog */
|
||||
}
|
||||
else if (config.syslog)
|
||||
{
|
||||
} else if (config.syslog) {
|
||||
if (godaemon == TRUE)
|
||||
openlog ("tinyproxy", LOG_PID, LOG_DAEMON);
|
||||
else
|
||||
openlog ("tinyproxy", LOG_PID, LOG_USER);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
fprintf (stderr,
|
||||
"%s: Either define a logfile or enable syslog logging.\n",
|
||||
argv[0]);
|
||||
@ -278,26 +262,23 @@ main (int argc, char **argv)
|
||||
/*
|
||||
* Set the default values if they were not set in the config file.
|
||||
*/
|
||||
if (config.port == 0)
|
||||
{
|
||||
if (config.port == 0) {
|
||||
fprintf (stderr,
|
||||
"%s: You MUST set a Port in the configuration file.\n",
|
||||
argv[0]);
|
||||
exit (EX_SOFTWARE);
|
||||
}
|
||||
if (!config.stathost)
|
||||
{
|
||||
log_message (LOG_INFO, "Setting stathost to \"%s\".", DEFAULT_STATHOST);
|
||||
if (!config.stathost) {
|
||||
log_message (LOG_INFO, "Setting stathost to \"%s\".",
|
||||
DEFAULT_STATHOST);
|
||||
config.stathost = DEFAULT_STATHOST;
|
||||
}
|
||||
if (!config.user)
|
||||
{
|
||||
if (!config.user) {
|
||||
log_message (LOG_WARNING,
|
||||
"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,
|
||||
"Invalid idle time setting. Only values greater than zero "
|
||||
"allowed; therefore setting idle timeout to %u seconds.",
|
||||
@ -314,8 +295,7 @@ main (int argc, char **argv)
|
||||
* hand in hand with Content-Length.
|
||||
* - rjkaes
|
||||
*/
|
||||
if (is_anonymous_enabled ())
|
||||
{
|
||||
if (is_anonymous_enabled ()) {
|
||||
anonymous_insert ("Content-Length");
|
||||
anonymous_insert ("Content-Type");
|
||||
}
|
||||
@ -323,17 +303,15 @@ main (int argc, char **argv)
|
||||
if (godaemon == TRUE)
|
||||
makedaemon ();
|
||||
|
||||
if (config.pidpath)
|
||||
{
|
||||
if (pidfile_create (config.pidpath) < 0)
|
||||
{
|
||||
fprintf (stderr, "%s: Could not create PID file.\n", argv[0]);
|
||||
if (config.pidpath) {
|
||||
if (pidfile_create (config.pidpath) < 0) {
|
||||
fprintf (stderr, "%s: Could not create PID file.\n",
|
||||
argv[0]);
|
||||
exit (EX_OSERR);
|
||||
}
|
||||
}
|
||||
|
||||
if (set_signal_handler (SIGPIPE, SIG_IGN) == SIG_ERR)
|
||||
{
|
||||
if (set_signal_handler (SIGPIPE, SIG_IGN) == SIG_ERR) {
|
||||
fprintf (stderr, "%s: Could not set the \"SIGPIPE\" signal.\n",
|
||||
argv[0]);
|
||||
exit (EX_OSERR);
|
||||
@ -346,76 +324,69 @@ main (int argc, char **argv)
|
||||
/*
|
||||
* Start listening on the selected port.
|
||||
*/
|
||||
if (child_listening_sock (config.port) < 0)
|
||||
{
|
||||
fprintf (stderr, "%s: Could not create listening socket.\n", argv[0]);
|
||||
if (child_listening_sock (config.port) < 0) {
|
||||
fprintf (stderr, "%s: Could not create listening socket.\n",
|
||||
argv[0]);
|
||||
exit (EX_OSERR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Switch to a different user.
|
||||
*/
|
||||
if (geteuid () == 0)
|
||||
{
|
||||
if (config.group && strlen (config.group) > 0)
|
||||
{
|
||||
if (geteuid () == 0) {
|
||||
if (config.group && strlen (config.group) > 0) {
|
||||
int gid = get_id (config.group);
|
||||
if (gid < 0)
|
||||
{
|
||||
if (gid < 0) {
|
||||
thisgroup = getgrnam (config.group);
|
||||
if (!thisgroup)
|
||||
{
|
||||
if (!thisgroup) {
|
||||
fprintf (stderr,
|
||||
"%s: Unable to find "
|
||||
"group \"%s\".\n", argv[0], config.group);
|
||||
"group \"%s\".\n", argv[0],
|
||||
config.group);
|
||||
exit (EX_NOUSER);
|
||||
}
|
||||
gid = thisgroup->gr_gid;
|
||||
}
|
||||
if (setgid (gid) < 0)
|
||||
{
|
||||
if (setgid (gid) < 0) {
|
||||
fprintf (stderr,
|
||||
"%s: Unable to change to "
|
||||
"group \"%s\".\n", argv[0], config.group);
|
||||
"group \"%s\".\n", argv[0],
|
||||
config.group);
|
||||
exit (EX_CANTCREAT);
|
||||
}
|
||||
log_message (LOG_INFO, "Now running as group \"%s\".",
|
||||
config.group);
|
||||
}
|
||||
if (config.user && strlen (config.user) > 0)
|
||||
{
|
||||
if (config.user && strlen (config.user) > 0) {
|
||||
int uid = get_id (config.user);
|
||||
if (uid < 0)
|
||||
{
|
||||
if (uid < 0) {
|
||||
thisuser = getpwnam (config.user);
|
||||
if (!thisuser)
|
||||
{
|
||||
if (!thisuser) {
|
||||
fprintf (stderr,
|
||||
"%s: Unable to find "
|
||||
"user \"%s\".\n", argv[0], config.user);
|
||||
"user \"%s\".\n", argv[0],
|
||||
config.user);
|
||||
exit (EX_NOUSER);
|
||||
}
|
||||
uid = thisuser->pw_uid;
|
||||
}
|
||||
if (setuid (uid) < 0)
|
||||
{
|
||||
if (setuid (uid) < 0) {
|
||||
fprintf (stderr,
|
||||
"%s: Unable to change to user \"%s\".\n",
|
||||
argv[0], config.user);
|
||||
exit (EX_CANTCREAT);
|
||||
}
|
||||
log_message (LOG_INFO, "Now running as user \"%s\".", config.user);
|
||||
log_message (LOG_INFO, "Now running as user \"%s\".",
|
||||
config.user);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
log_message (LOG_WARNING,
|
||||
"Not running as root, so not changing UID/GID.");
|
||||
}
|
||||
|
||||
if (child_pool_create () < 0)
|
||||
{
|
||||
fprintf (stderr, "%s: Could not create the pool of children.\n", argv[0]);
|
||||
if (child_pool_create () < 0) {
|
||||
fprintf (stderr, "%s: Could not create the pool of children.\n",
|
||||
argv[0]);
|
||||
exit (EX_SOFTWARE);
|
||||
}
|
||||
|
||||
@ -423,21 +394,19 @@ main (int argc, char **argv)
|
||||
* These signals are only for the parent process.
|
||||
*/
|
||||
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",
|
||||
argv[0]);
|
||||
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",
|
||||
argv[0]);
|
||||
exit (EX_OSERR);
|
||||
}
|
||||
if (set_signal_handler (SIGHUP, takesig) == SIG_ERR)
|
||||
{
|
||||
fprintf (stderr, "%s: Could not set the \"SIGHUP\" signal.\n", argv[0]);
|
||||
if (set_signal_handler (SIGHUP, takesig) == SIG_ERR) {
|
||||
fprintf (stderr, "%s: Could not set the \"SIGHUP\" signal.\n",
|
||||
argv[0]);
|
||||
exit (EX_OSERR);
|
||||
}
|
||||
|
||||
@ -456,8 +425,7 @@ main (int argc, char **argv)
|
||||
/*
|
||||
* Remove the PID file.
|
||||
*/
|
||||
if (unlink (config.pidpath) < 0)
|
||||
{
|
||||
if (unlink (config.pidpath) < 0) {
|
||||
log_message (LOG_WARNING,
|
||||
"Could not remove PID file \"%s\": %s.",
|
||||
config.pidpath, strerror (errno));
|
||||
|
@ -33,8 +33,7 @@
|
||||
* Even if upstream support is not compiled into tinyproxy, this
|
||||
* structure still needs to be defined.
|
||||
*/
|
||||
struct upstream
|
||||
{
|
||||
struct upstream {
|
||||
struct upstream *next;
|
||||
char *domain; /* optional */
|
||||
char *host;
|
||||
@ -45,8 +44,7 @@ struct upstream
|
||||
/*
|
||||
* Hold all the configuration time information.
|
||||
*/
|
||||
struct config_s
|
||||
{
|
||||
struct config_s {
|
||||
char *logf_name;
|
||||
const char *config_file;
|
||||
unsigned int syslog; /* boolean */
|
||||
|
@ -32,8 +32,7 @@
|
||||
* Write the buffer to the socket. If an EINTR occurs, pick up and try
|
||||
* again. Keep sending until the buffer has been sent.
|
||||
*/
|
||||
ssize_t
|
||||
safe_write (int fd, const char *buffer, size_t count)
|
||||
ssize_t safe_write (int fd, const char *buffer, size_t count)
|
||||
{
|
||||
ssize_t len;
|
||||
size_t bytestosend;
|
||||
@ -44,19 +43,17 @@ safe_write (int fd, const char *buffer, size_t count)
|
||||
|
||||
bytestosend = count;
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (1) {
|
||||
len = send (fd, buffer, bytestosend, MSG_NOSIGNAL);
|
||||
|
||||
if (len < 0)
|
||||
{
|
||||
if (len < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
else
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if ((size_t)len == bytestosend)
|
||||
if ((size_t) len == bytestosend)
|
||||
break;
|
||||
|
||||
buffer += len;
|
||||
@ -70,16 +67,13 @@ safe_write (int fd, const char *buffer, size_t count)
|
||||
* Matched pair for safe_write(). If an EINTR occurs, pick up and try
|
||||
* again.
|
||||
*/
|
||||
ssize_t
|
||||
safe_read (int fd, char *buffer, size_t count)
|
||||
ssize_t safe_read (int fd, char *buffer, size_t count)
|
||||
{
|
||||
ssize_t len;
|
||||
|
||||
do
|
||||
{
|
||||
do {
|
||||
len = read (fd, buffer, count);
|
||||
}
|
||||
while (len < 0 && errno == EINTR);
|
||||
} while (len < 0 && errno == EINTR);
|
||||
|
||||
return len;
|
||||
}
|
||||
@ -90,25 +84,23 @@ safe_read (int fd, char *buffer, size_t count)
|
||||
* was basically stolen from the snprintf() man page of Debian Linux
|
||||
* (although I did fix a memory leak. :)
|
||||
*/
|
||||
int
|
||||
write_message (int fd, const char *fmt, ...)
|
||||
int write_message (int fd, const char *fmt, ...)
|
||||
{
|
||||
ssize_t n;
|
||||
size_t size = (1024 * 8); /* start with 8 KB and go from there */
|
||||
char *buf, *tmpbuf;
|
||||
va_list ap;
|
||||
|
||||
if ((buf = (char *)safemalloc (size)) == NULL)
|
||||
if ((buf = (char *) safemalloc (size)) == NULL)
|
||||
return -1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (1) {
|
||||
va_start (ap, fmt);
|
||||
n = vsnprintf (buf, size, fmt, ap);
|
||||
va_end (ap);
|
||||
|
||||
/* If that worked, break out so we can send the buffer */
|
||||
if (n > -1 && (size_t)n < size)
|
||||
if (n > -1 && (size_t) n < size)
|
||||
break;
|
||||
|
||||
/* Else, try again with more space */
|
||||
@ -119,17 +111,14 @@ write_message (int fd, const char *fmt, ...)
|
||||
/* twice the old size (glibc2.0) */
|
||||
size *= 2;
|
||||
|
||||
if ((tmpbuf = (char *)saferealloc (buf, size)) == NULL)
|
||||
{
|
||||
if ((tmpbuf = (char *) saferealloc (buf, size)) == NULL) {
|
||||
safefree (buf);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
} else
|
||||
buf = tmpbuf;
|
||||
}
|
||||
|
||||
if (safe_write (fd, buf, n) < 0)
|
||||
{
|
||||
if (safe_write (fd, buf, n) < 0) {
|
||||
safefree (buf);
|
||||
return -1;
|
||||
}
|
||||
@ -149,8 +138,7 @@ write_message (int fd, const char *fmt, ...)
|
||||
*/
|
||||
#define SEGMENT_LEN (512)
|
||||
#define MAXIMUM_BUFFER_LENGTH (128 * 1024)
|
||||
ssize_t
|
||||
readline (int fd, char **whole_buffer)
|
||||
ssize_t readline (int fd, char **whole_buffer)
|
||||
{
|
||||
ssize_t whole_buffer_len;
|
||||
char buffer[SEGMENT_LEN];
|
||||
@ -159,15 +147,15 @@ readline (int fd, char **whole_buffer)
|
||||
ssize_t ret;
|
||||
ssize_t diff;
|
||||
|
||||
struct read_lines_s
|
||||
{
|
||||
struct read_lines_s {
|
||||
char *data;
|
||||
size_t len;
|
||||
struct read_lines_s *next;
|
||||
};
|
||||
struct read_lines_s *first_line, *line_ptr;
|
||||
|
||||
first_line = (struct read_lines_s *)safecalloc (sizeof (struct read_lines_s),
|
||||
first_line =
|
||||
(struct read_lines_s *) safecalloc (sizeof (struct read_lines_s),
|
||||
1);
|
||||
if (!first_line)
|
||||
return -ENOMEM;
|
||||
@ -175,13 +163,12 @@ readline (int fd, char **whole_buffer)
|
||||
line_ptr = first_line;
|
||||
|
||||
whole_buffer_len = 0;
|
||||
for (;;)
|
||||
{
|
||||
for (;;) {
|
||||
ret = recv (fd, buffer, SEGMENT_LEN, MSG_PEEK);
|
||||
if (ret <= 0)
|
||||
goto CLEANUP;
|
||||
|
||||
ptr = (char *)memchr (buffer, '\n', ret);
|
||||
ptr = (char *) memchr (buffer, '\n', ret);
|
||||
if (ptr)
|
||||
diff = ptr - buffer + 1;
|
||||
else
|
||||
@ -193,15 +180,13 @@ readline (int fd, char **whole_buffer)
|
||||
* Don't allow the buffer to grow without bound. If we
|
||||
* get to more than MAXIMUM_BUFFER_LENGTH close.
|
||||
*/
|
||||
if (whole_buffer_len > MAXIMUM_BUFFER_LENGTH)
|
||||
{
|
||||
if (whole_buffer_len > MAXIMUM_BUFFER_LENGTH) {
|
||||
ret = -ERANGE;
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
line_ptr->data = (char *)safemalloc (diff);
|
||||
if (!line_ptr->data)
|
||||
{
|
||||
line_ptr->data = (char *) safemalloc (diff);
|
||||
if (!line_ptr->data) {
|
||||
ret = -ENOMEM;
|
||||
goto CLEANUP;
|
||||
}
|
||||
@ -209,25 +194,23 @@ readline (int fd, char **whole_buffer)
|
||||
recv (fd, line_ptr->data, diff, 0);
|
||||
line_ptr->len = diff;
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
if (ptr) {
|
||||
line_ptr->next = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
line_ptr->next =
|
||||
(struct read_lines_s *)safecalloc (sizeof (struct read_lines_s), 1);
|
||||
if (!line_ptr->next)
|
||||
{
|
||||
(struct read_lines_s *)
|
||||
safecalloc (sizeof (struct read_lines_s), 1);
|
||||
if (!line_ptr->next) {
|
||||
ret = -ENOMEM;
|
||||
goto CLEANUP;
|
||||
}
|
||||
line_ptr = line_ptr->next;
|
||||
}
|
||||
|
||||
*whole_buffer = (char *)safemalloc (whole_buffer_len + 1);
|
||||
if (!*whole_buffer)
|
||||
{
|
||||
*whole_buffer = (char *) safemalloc (whole_buffer_len + 1);
|
||||
if (!*whole_buffer) {
|
||||
ret = -ENOMEM;
|
||||
goto CLEANUP;
|
||||
}
|
||||
@ -236,8 +219,7 @@ readline (int fd, char **whole_buffer)
|
||||
|
||||
whole_buffer_len = 0;
|
||||
line_ptr = first_line;
|
||||
while (line_ptr)
|
||||
{
|
||||
while (line_ptr) {
|
||||
memcpy (*whole_buffer + whole_buffer_len, line_ptr->data,
|
||||
line_ptr->len);
|
||||
whole_buffer_len += line_ptr->len;
|
||||
@ -248,15 +230,13 @@ readline (int fd, char **whole_buffer)
|
||||
ret = whole_buffer_len;
|
||||
|
||||
CLEANUP:
|
||||
do
|
||||
{
|
||||
do {
|
||||
line_ptr = first_line->next;
|
||||
if (first_line->data)
|
||||
safefree (first_line->data);
|
||||
safefree (first_line);
|
||||
first_line = line_ptr;
|
||||
}
|
||||
while (first_line);
|
||||
} while (first_line);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -265,16 +245,14 @@ CLEANUP:
|
||||
* Convert the network address into either a dotted-decimal or an IPv6
|
||||
* hex string.
|
||||
*/
|
||||
char *
|
||||
get_ip_string (struct sockaddr *sa, char *buf, size_t buflen)
|
||||
char *get_ip_string (struct sockaddr *sa, char *buf, size_t buflen)
|
||||
{
|
||||
assert (sa != NULL);
|
||||
assert (buf != NULL);
|
||||
assert (buflen != 0);
|
||||
buf[0] = '\0'; /* start with an empty string */
|
||||
|
||||
switch (sa->sa_family)
|
||||
{
|
||||
switch (sa->sa_family) {
|
||||
case AF_INET:
|
||||
{
|
||||
struct sockaddr_in *sa_in = (struct sockaddr_in *) sa;
|
||||
@ -284,7 +262,8 @@ get_ip_string (struct sockaddr *sa, char *buf, size_t buflen)
|
||||
}
|
||||
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);
|
||||
break;
|
||||
@ -304,8 +283,7 @@ get_ip_string (struct sockaddr *sa, char *buf, size_t buflen)
|
||||
*
|
||||
* Returns the same as inet_pton().
|
||||
*/
|
||||
int
|
||||
full_inet_pton (const char *ip, void *dst)
|
||||
int full_inet_pton (const char *ip, void *dst)
|
||||
{
|
||||
char buf[24], tmp[24]; /* IPv4->IPv6 = ::FFFF:xxx.xxx.xxx.xxx\0 */
|
||||
int n;
|
||||
@ -319,8 +297,7 @@ full_inet_pton (const char *ip, void *dst)
|
||||
* address formats.
|
||||
*/
|
||||
n = inet_aton (ip, (struct in_addr *) dst);
|
||||
if (n == 0)
|
||||
{
|
||||
if (n == 0) {
|
||||
/*
|
||||
* Simple case: "ip" wasn't an IPv4 numeric address, so
|
||||
* try doing the conversion as an IPv6 address. This
|
||||
|
559
src/reqs.c
559
src/reqs.c
File diff suppressed because it is too large
Load Diff
@ -24,7 +24,6 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
/*
|
||||
* Port constants for HTTP (80) and SSL (443)
|
||||
*/
|
||||
@ -34,8 +33,7 @@
|
||||
/*
|
||||
* This structure holds the information pulled from a URL request.
|
||||
*/
|
||||
struct request_s
|
||||
{
|
||||
struct request_s {
|
||||
char *method;
|
||||
char *protocol;
|
||||
|
||||
|
@ -29,36 +29,33 @@
|
||||
/*
|
||||
* Add entry to the reversepath list
|
||||
*/
|
||||
void
|
||||
reversepath_add (const char *path, const char *url)
|
||||
void reversepath_add (const char *path, const char *url)
|
||||
{
|
||||
struct reversepath *reverse;
|
||||
|
||||
if (url == NULL)
|
||||
{
|
||||
log_message (LOG_WARNING, "Illegal reverse proxy rule: missing url");
|
||||
if (url == NULL) {
|
||||
log_message (LOG_WARNING,
|
||||
"Illegal reverse proxy rule: missing url");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strstr (url, "://"))
|
||||
{
|
||||
if (!strstr (url, "://")) {
|
||||
log_message (LOG_WARNING,
|
||||
"Skipping reverse proxy rule: '%s' is not a valid url",
|
||||
url);
|
||||
return;
|
||||
}
|
||||
|
||||
if (path && *path != '/')
|
||||
{
|
||||
if (path && *path != '/') {
|
||||
log_message (LOG_WARNING,
|
||||
"Skipping reverse proxy rule: path '%s' "
|
||||
"doesn't start with a /", path);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(reverse = safemalloc (sizeof (struct reversepath))))
|
||||
{
|
||||
log_message (LOG_ERR, "Unable to allocate memory in reversepath_add()");
|
||||
if (!(reverse = safemalloc (sizeof (struct reversepath)))) {
|
||||
log_message (LOG_ERR,
|
||||
"Unable to allocate memory in reversepath_add()");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -80,13 +77,11 @@ reversepath_add (const char *path, const char *url)
|
||||
/*
|
||||
* Check if a request url is in the reversepath list
|
||||
*/
|
||||
struct reversepath *
|
||||
reversepath_get (char *url)
|
||||
struct reversepath *reversepath_get (char *url)
|
||||
{
|
||||
struct reversepath *reverse = config.reversepath_list;
|
||||
|
||||
while (reverse)
|
||||
{
|
||||
while (reverse) {
|
||||
if (strstr (url, reverse->path) == url)
|
||||
return reverse;
|
||||
|
||||
@ -99,8 +94,7 @@ reversepath_get (char *url)
|
||||
/*
|
||||
* Rewrite the URL for reverse proxying.
|
||||
*/
|
||||
char *
|
||||
reverse_rewrite_url (struct conn_s *connptr, hashmap_t hashofheaders,
|
||||
char *reverse_rewrite_url (struct conn_s *connptr, hashmap_t hashofheaders,
|
||||
char *url)
|
||||
{
|
||||
char *rewrite_url = NULL;
|
||||
@ -109,45 +103,47 @@ reverse_rewrite_url (struct conn_s *connptr, hashmap_t hashofheaders,
|
||||
struct reversepath *reverse;
|
||||
|
||||
/* Reverse requests always start with a slash */
|
||||
if (*url == '/')
|
||||
{
|
||||
if (*url == '/') {
|
||||
/* First try locating the reverse mapping by request url */
|
||||
reverse = reversepath_get (url);
|
||||
if (reverse)
|
||||
{
|
||||
rewrite_url = safemalloc (strlen (url) + strlen (reverse->url) + 1);
|
||||
if (reverse) {
|
||||
rewrite_url =
|
||||
safemalloc (strlen (url) + strlen (reverse->url) +
|
||||
1);
|
||||
strcpy (rewrite_url, reverse->url);
|
||||
strcat (rewrite_url, url + strlen (reverse->path));
|
||||
}
|
||||
else if (config.reversemagic
|
||||
} else if (config.reversemagic
|
||||
&& hashmap_entry_by_key (hashofheaders,
|
||||
"cookie", (void **) &cookie) > 0)
|
||||
{
|
||||
"cookie",
|
||||
(void **) &cookie) > 0) {
|
||||
|
||||
/* No match - try the magical tracking cookie next */
|
||||
if ((cookieval = strstr (cookie, REVERSE_COOKIE "="))
|
||||
&& (reverse =
|
||||
reversepath_get (cookieval + strlen (REVERSE_COOKIE) + 1)))
|
||||
{
|
||||
reversepath_get (cookieval +
|
||||
strlen (REVERSE_COOKIE) +
|
||||
1))) {
|
||||
|
||||
rewrite_url = safemalloc (strlen (url) +
|
||||
strlen (reverse->url) + 1);
|
||||
strlen (reverse->
|
||||
url) + 1);
|
||||
strcpy (rewrite_url, reverse->url);
|
||||
strcat (rewrite_url, url + 1);
|
||||
|
||||
log_message (LOG_INFO,
|
||||
"Magical tracking cookie says: %s", reverse->path);
|
||||
"Magical tracking cookie says: %s",
|
||||
reverse->path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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",
|
||||
"detail",
|
||||
"Request has an invalid URL", "url", url, NULL);
|
||||
"Request has an invalid URL", "url", url,
|
||||
NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,7 @@
|
||||
|
||||
#include "conns.h"
|
||||
|
||||
struct reversepath
|
||||
{
|
||||
struct reversepath {
|
||||
struct reversepath *next;
|
||||
char *path;
|
||||
char *url;
|
||||
|
80
src/sock.c
80
src/sock.c
@ -38,8 +38,7 @@
|
||||
* returned if the bind succeeded. Otherwise, -1 is returned
|
||||
* to indicate an error.
|
||||
*/
|
||||
static int
|
||||
bind_socket (int sockfd, const char *addr)
|
||||
static int bind_socket (int sockfd, const char *addr)
|
||||
{
|
||||
struct addrinfo hints, *res, *ressave;
|
||||
|
||||
@ -57,12 +56,10 @@ bind_socket (int sockfd, const char *addr)
|
||||
ressave = res;
|
||||
|
||||
/* Loop through the addresses and try to bind to each */
|
||||
do
|
||||
{
|
||||
do {
|
||||
if (bind (sockfd, res->ai_addr, res->ai_addrlen) == 0)
|
||||
break; /* success */
|
||||
}
|
||||
while ((res = res->ai_next) != NULL);
|
||||
} while ((res = res->ai_next) != NULL);
|
||||
|
||||
freeaddrinfo (ressave);
|
||||
if (res == NULL) /* was not able to bind to any address */
|
||||
@ -76,8 +73,7 @@ bind_socket (int sockfd, const char *addr)
|
||||
* the getaddrinfo() library function, which allows for a protocol
|
||||
* independent implementation (mostly for IPv4 and IPv6 addresses.)
|
||||
*/
|
||||
int
|
||||
opensock (const char *host, int port, const char *bind_to)
|
||||
int opensock (const char *host, int port, const char *bind_to)
|
||||
{
|
||||
int sockfd, n;
|
||||
struct addrinfo hints, *res, *ressave;
|
||||
@ -93,32 +89,27 @@ opensock (const char *host, int port, const char *bind_to)
|
||||
snprintf (portstr, sizeof (portstr), "%d", port);
|
||||
|
||||
n = getaddrinfo (host, portstr, &hints, &res);
|
||||
if (n != 0)
|
||||
{
|
||||
log_message (LOG_ERR, "opensock: Could not retrieve info for %s", host);
|
||||
if (n != 0) {
|
||||
log_message (LOG_ERR,
|
||||
"opensock: Could not retrieve info for %s", host);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ressave = res;
|
||||
do
|
||||
{
|
||||
sockfd = socket (res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
do {
|
||||
sockfd =
|
||||
socket (res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
if (sockfd < 0)
|
||||
continue; /* ignore this one */
|
||||
|
||||
/* Bind to the specified address */
|
||||
if (bind_to)
|
||||
{
|
||||
if (bind_socket (sockfd, bind_to) < 0)
|
||||
{
|
||||
if (bind_to) {
|
||||
if (bind_socket (sockfd, bind_to) < 0) {
|
||||
close (sockfd);
|
||||
continue; /* can't bind, so try again */
|
||||
}
|
||||
}
|
||||
else if (config.bind_address)
|
||||
{
|
||||
if (bind_socket (sockfd, config.bind_address) < 0)
|
||||
{
|
||||
} else if (config.bind_address) {
|
||||
if (bind_socket (sockfd, config.bind_address) < 0) {
|
||||
close (sockfd);
|
||||
continue; /* can't bind, so try again */
|
||||
}
|
||||
@ -128,14 +119,13 @@ opensock (const char *host, int port, const char *bind_to)
|
||||
break; /* success */
|
||||
|
||||
close (sockfd);
|
||||
}
|
||||
while ((res = res->ai_next) != NULL);
|
||||
} while ((res = res->ai_next) != NULL);
|
||||
|
||||
freeaddrinfo (ressave);
|
||||
if (res == NULL)
|
||||
{
|
||||
if (res == NULL) {
|
||||
log_message (LOG_ERR,
|
||||
"opensock: Could not establish a connection to %s", host);
|
||||
"opensock: Could not establish a connection to %s",
|
||||
host);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -145,8 +135,7 @@ opensock (const char *host, int port, const char *bind_to)
|
||||
/*
|
||||
* Set the socket to non blocking -rjkaes
|
||||
*/
|
||||
int
|
||||
socket_nonblocking (int sock)
|
||||
int socket_nonblocking (int sock)
|
||||
{
|
||||
int flags;
|
||||
|
||||
@ -159,8 +148,7 @@ socket_nonblocking (int sock)
|
||||
/*
|
||||
* Set the socket to blocking -rjkaes
|
||||
*/
|
||||
int
|
||||
socket_blocking (int sock)
|
||||
int socket_blocking (int sock)
|
||||
{
|
||||
int flags;
|
||||
|
||||
@ -176,8 +164,7 @@ socket_blocking (int sock)
|
||||
* the pointer, while the socket is returned as a default return.
|
||||
* - rjkaes
|
||||
*/
|
||||
int
|
||||
listen_sock (uint16_t port, socklen_t * addrlen)
|
||||
int listen_sock (uint16_t port, socklen_t * addrlen)
|
||||
{
|
||||
int listenfd;
|
||||
const int on = 1;
|
||||
@ -193,25 +180,20 @@ listen_sock (uint16_t port, socklen_t * addrlen)
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons (port);
|
||||
|
||||
if (config.ipAddr)
|
||||
{
|
||||
if (config.ipAddr) {
|
||||
addr.sin_addr.s_addr = inet_addr (config.ipAddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
} 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,
|
||||
"Unable to bind listening socket because of %s",
|
||||
strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen (listenfd, MAXLISTEN) < 0)
|
||||
{
|
||||
if (listen (listenfd, MAXLISTEN) < 0) {
|
||||
log_message (LOG_ERR,
|
||||
"Unable to start listening socket because of %s",
|
||||
strerror (errno));
|
||||
@ -226,22 +208,21 @@ listen_sock (uint16_t port, socklen_t * addrlen)
|
||||
/*
|
||||
* Takes a socket descriptor and returns the socket's IP address.
|
||||
*/
|
||||
int
|
||||
getsock_ip (int fd, char *ipaddr)
|
||||
int getsock_ip (int fd, char *ipaddr)
|
||||
{
|
||||
struct sockaddr_storage name;
|
||||
socklen_t namelen = sizeof (name);
|
||||
|
||||
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));
|
||||
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 0;
|
||||
@ -250,8 +231,7 @@ getsock_ip (int fd, char *ipaddr)
|
||||
/*
|
||||
* Return the peer's socket information.
|
||||
*/
|
||||
int
|
||||
getpeer_information (int fd, char *ipaddr, char *string_addr)
|
||||
int getpeer_information (int fd, char *ipaddr, char *string_addr)
|
||||
{
|
||||
struct sockaddr_storage sa;
|
||||
socklen_t salen = sizeof sa;
|
||||
|
28
src/stats.c
28
src/stats.c
@ -33,8 +33,7 @@
|
||||
#include "stats.h"
|
||||
#include "utils.h"
|
||||
|
||||
struct stat_s
|
||||
{
|
||||
struct stat_s {
|
||||
unsigned long int num_reqs;
|
||||
unsigned long int num_badcons;
|
||||
unsigned long int num_open;
|
||||
@ -47,10 +46,9 @@ static struct stat_s *stats;
|
||||
/*
|
||||
* Initialize the statistics information to zero.
|
||||
*/
|
||||
void
|
||||
init_stats (void)
|
||||
void init_stats (void)
|
||||
{
|
||||
stats = (struct stat_s *)malloc_shared_memory (sizeof (struct stat_s));
|
||||
stats = (struct stat_s *) malloc_shared_memory (sizeof (struct stat_s));
|
||||
if (stats == MAP_FAILED)
|
||||
return;
|
||||
|
||||
@ -60,8 +58,7 @@ init_stats (void)
|
||||
/*
|
||||
* Display the statics of the tinyproxy server.
|
||||
*/
|
||||
int
|
||||
showstats (struct conn_s *connptr)
|
||||
int showstats (struct conn_s *connptr)
|
||||
{
|
||||
static const char *msg =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
|
||||
@ -79,7 +76,8 @@ showstats (struct conn_s *connptr)
|
||||
"Number of refused connections due to high load: %lu\n"
|
||||
"</p>\n"
|
||||
"<hr />\n"
|
||||
"<p><em>Generated by %s version %s.</em></p>\n" "</body>\n" "</html>\n";
|
||||
"<p><em>Generated by %s version %s.</em></p>\n" "</body>\n"
|
||||
"</html>\n";
|
||||
|
||||
char *message_buffer;
|
||||
char opens[16], reqs[16], badconns[16], denied[16], refused[16];
|
||||
@ -91,9 +89,8 @@ showstats (struct conn_s *connptr)
|
||||
snprintf (denied, sizeof (denied), "%lu", stats->num_denied);
|
||||
snprintf (refused, sizeof (refused), "%lu", stats->num_refused);
|
||||
|
||||
if (!config.statpage || (!(statfile = fopen (config.statpage, "r"))))
|
||||
{
|
||||
message_buffer = (char *)safemalloc (MAXBUFFSIZE);
|
||||
if (!config.statpage || (!(statfile = fopen (config.statpage, "r")))) {
|
||||
message_buffer = (char *) safemalloc (MAXBUFFSIZE);
|
||||
if (!message_buffer)
|
||||
return -1;
|
||||
|
||||
@ -104,8 +101,7 @@ showstats (struct conn_s *connptr)
|
||||
stats->num_badcons, stats->num_denied,
|
||||
stats->num_refused, 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);
|
||||
return -1;
|
||||
}
|
||||
@ -131,11 +127,9 @@ showstats (struct conn_s *connptr)
|
||||
* Update the value of the statistics. The update_level is defined in
|
||||
* stats.h
|
||||
*/
|
||||
int
|
||||
update_stats (status_t update_level)
|
||||
int update_stats (status_t update_level)
|
||||
{
|
||||
switch (update_level)
|
||||
{
|
||||
switch (update_level) {
|
||||
case STAT_BADCONN:
|
||||
++stats->num_badcons;
|
||||
break;
|
||||
|
@ -26,8 +26,7 @@
|
||||
/*
|
||||
* Various logable statistics
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
STAT_BADCONN, /* bad connection, for unknown reason */
|
||||
STAT_OPEN, /* connection opened */
|
||||
STAT_CLOSE, /* connection closed */
|
||||
|
15
src/text.c
15
src/text.c
@ -32,8 +32,7 @@
|
||||
* buffer, and always NULL terminates the buffer. size is the size of the
|
||||
* destination buffer.
|
||||
*/
|
||||
size_t
|
||||
strlcpy (char *dst, const char *src, size_t size)
|
||||
size_t strlcpy (char *dst, const char *src, size_t size)
|
||||
{
|
||||
size_t len = strlen (src);
|
||||
size_t ret = len;
|
||||
@ -55,8 +54,7 @@ strlcpy (char *dst, const char *src, size_t size)
|
||||
* buffer, which should be one more than the maximum resulting string
|
||||
* length.
|
||||
*/
|
||||
size_t
|
||||
strlcat (char *dst, const char *src, size_t size)
|
||||
size_t strlcat (char *dst, const char *src, size_t size)
|
||||
{
|
||||
size_t len1 = strlen (dst);
|
||||
size_t len2 = strlen (src);
|
||||
@ -64,8 +62,7 @@ strlcat (char *dst, const char *src, size_t size)
|
||||
|
||||
if (len1 + len2 >= size)
|
||||
len2 = size - len1 - 1;
|
||||
if (len2 > 0)
|
||||
{
|
||||
if (len2 > 0) {
|
||||
memcpy (dst + len1, src, len2);
|
||||
dst[len1 + len2] = '\0';
|
||||
}
|
||||
@ -83,8 +80,7 @@ strlcat (char *dst, const char *src, size_t size)
|
||||
* Returns the number of characters removed from the end of the string. A
|
||||
* negative return value indicates an error.
|
||||
*/
|
||||
ssize_t
|
||||
chomp (char *buffer, size_t length)
|
||||
ssize_t chomp (char *buffer, size_t length)
|
||||
{
|
||||
size_t chars;
|
||||
|
||||
@ -100,8 +96,7 @@ chomp (char *buffer, size_t length)
|
||||
chars = 0;
|
||||
|
||||
--length;
|
||||
while (buffer[length] == '\r' || buffer[length] == '\n')
|
||||
{
|
||||
while (buffer[length] == '\r' || buffer[length] == '\n') {
|
||||
buffer[length] = '\0';
|
||||
chars++;
|
||||
|
||||
|
@ -35,8 +35,7 @@
|
||||
/*
|
||||
* Build a URL from parts.
|
||||
*/
|
||||
static int
|
||||
build_url (char **url, const char *host, int port, const char *path)
|
||||
static int build_url (char **url, const char *host, int port, const char *path)
|
||||
{
|
||||
int len;
|
||||
|
||||
@ -53,7 +52,6 @@ build_url (char **url, const char *host, int port, const char *path)
|
||||
return snprintf (*url, len, "http://%s:%d%s", host, port, path);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
do_transparent_proxy (struct conn_s *connptr, hashmap_t hashofheaders,
|
||||
struct request_s *request, struct config_s *conf,
|
||||
@ -63,19 +61,18 @@ do_transparent_proxy (struct conn_s *connptr, hashmap_t hashofheaders,
|
||||
char *data;
|
||||
|
||||
length = hashmap_entry_by_key (hashofheaders, "host", (void **) &data);
|
||||
if (length <= 0)
|
||||
{
|
||||
if (length <= 0) {
|
||||
struct sockaddr_in dest_addr;
|
||||
|
||||
if (getsockname
|
||||
(connptr->client_fd, (struct sockaddr *) &dest_addr, &length) < 0)
|
||||
{
|
||||
(connptr->client_fd, (struct sockaddr *) &dest_addr,
|
||||
&length) < 0) {
|
||||
log_message (LOG_ERR,
|
||||
"process_request: cannot get destination IP for %d",
|
||||
connptr->client_fd);
|
||||
indicate_http_error (connptr, 400, "Bad Request",
|
||||
"detail",
|
||||
"Unknown destination", "url", url, NULL);
|
||||
"detail", "Unknown destination",
|
||||
"url", url, NULL);
|
||||
return 0;
|
||||
}
|
||||
request->host = safemalloc (17);
|
||||
@ -88,12 +85,10 @@ do_transparent_proxy (struct conn_s *connptr, hashmap_t hashofheaders,
|
||||
log_message (LOG_INFO,
|
||||
"process_request: trans IP %s %s for %d",
|
||||
request->method, url, connptr->client_fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
request->host = safemalloc (length + 1);
|
||||
if (sscanf (data, "%[^:]:%hu", request->host, &request->port) != 2)
|
||||
{
|
||||
if (sscanf (data, "%[^:]:%hu", request->host, &request->port) !=
|
||||
2) {
|
||||
strcpy (request->host, data);
|
||||
request->port = HTTP_PORT;
|
||||
}
|
||||
@ -105,15 +100,15 @@ do_transparent_proxy (struct conn_s *connptr, hashmap_t hashofheaders,
|
||||
"process_request: trans Host %s %s for %d",
|
||||
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,
|
||||
"process_request: destination IP is localhost %d",
|
||||
connptr->client_fd);
|
||||
indicate_http_error (connptr, 400, "Bad Request",
|
||||
"detail",
|
||||
"You tried to connect to the machine "
|
||||
"the proxy is running on", "url", url, NULL);
|
||||
"the proxy is running on", "url", url,
|
||||
NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,6 @@ extern int do_transparent_proxy (struct conn_s *connptr,
|
||||
struct request_s *request,
|
||||
struct config_s *config, char *url);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
42
src/utils.c
42
src/utils.c
@ -60,8 +60,7 @@ send_http_message (struct conn_s *connptr, int http_code,
|
||||
/*
|
||||
* Safely creates filename and returns the low-level file descriptor.
|
||||
*/
|
||||
int
|
||||
create_file_safely (const char *filename, unsigned int truncate_file)
|
||||
int create_file_safely (const char *filename, unsigned int truncate_file)
|
||||
{
|
||||
struct stat lstatinfo;
|
||||
int fildes;
|
||||
@ -71,14 +70,12 @@ create_file_safely (const char *filename, unsigned int truncate_file)
|
||||
* If it does exist, open it for writing and perform the fstat()
|
||||
* check.
|
||||
*/
|
||||
if (lstat (filename, &lstatinfo) < 0)
|
||||
{
|
||||
if (lstat (filename, &lstatinfo) < 0) {
|
||||
/*
|
||||
* If lstat() failed for any reason other than "file not
|
||||
* existing", exit.
|
||||
*/
|
||||
if (errno != ENOENT)
|
||||
{
|
||||
if (errno != ENOENT) {
|
||||
fprintf (stderr,
|
||||
"%s: Error checking file %s: %s\n",
|
||||
PACKAGE, filename, strerror (errno));
|
||||
@ -90,16 +87,13 @@ create_file_safely (const char *filename, unsigned int truncate_file)
|
||||
* sure an attacker can't slip in a file between the lstat()
|
||||
* and open()
|
||||
*/
|
||||
if ((fildes = open (filename, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"%s: Could not create file %s: %s\n",
|
||||
if ((fildes =
|
||||
open (filename, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0) {
|
||||
fprintf (stderr, "%s: Could not create file %s: %s\n",
|
||||
PACKAGE, filename, strerror (errno));
|
||||
return fildes;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
struct stat fstatinfo;
|
||||
int flags;
|
||||
|
||||
@ -110,8 +104,7 @@ create_file_safely (const char *filename, unsigned int truncate_file)
|
||||
/*
|
||||
* Open an existing file.
|
||||
*/
|
||||
if ((fildes = open (filename, flags)) < 0)
|
||||
{
|
||||
if ((fildes = open (filename, flags)) < 0) {
|
||||
fprintf (stderr,
|
||||
"%s: Could not open file %s: %s\n",
|
||||
PACKAGE, filename, strerror (errno));
|
||||
@ -125,8 +118,7 @@ create_file_safely (const char *filename, unsigned int truncate_file)
|
||||
if (fstat (fildes, &fstatinfo) < 0
|
||||
|| lstatinfo.st_mode != fstatinfo.st_mode
|
||||
|| lstatinfo.st_ino != fstatinfo.st_ino
|
||||
|| lstatinfo.st_dev != fstatinfo.st_dev)
|
||||
{
|
||||
|| lstatinfo.st_dev != fstatinfo.st_dev) {
|
||||
fprintf (stderr,
|
||||
"%s: The file %s has been changed before it could be opened\n",
|
||||
PACKAGE, filename);
|
||||
@ -141,8 +133,7 @@ create_file_safely (const char *filename, unsigned int truncate_file)
|
||||
* isn't strictly necessary because the fstat() vs lstat()
|
||||
* st_mode check would also find this)
|
||||
*/
|
||||
if (fstatinfo.st_nlink > 1 || !S_ISREG (lstatinfo.st_mode))
|
||||
{
|
||||
if (fstatinfo.st_nlink > 1 || !S_ISREG (lstatinfo.st_mode)) {
|
||||
fprintf (stderr,
|
||||
"%s: The file %s has too many links, "
|
||||
"or is not a regular file: %s\n",
|
||||
@ -170,10 +161,9 @@ create_file_safely (const char *filename, unsigned int truncate_file)
|
||||
ftruncate (fildes, 0);
|
||||
#else
|
||||
close (fildes);
|
||||
if ((fildes = open (filename, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"%s: Could not open file %s: %s.",
|
||||
if ((fildes =
|
||||
open (filename, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) {
|
||||
fprintf (stderr, "%s: Could not open file %s: %s.",
|
||||
PACKAGE, filename, strerror (errno));
|
||||
return fildes;
|
||||
}
|
||||
@ -186,8 +176,7 @@ create_file_safely (const char *filename, unsigned int truncate_file)
|
||||
/*
|
||||
* Write the PID of the program to the specified file.
|
||||
*/
|
||||
int
|
||||
pidfile_create (const char *filename)
|
||||
int pidfile_create (const char *filename)
|
||||
{
|
||||
int fildes;
|
||||
FILE *fd;
|
||||
@ -201,8 +190,7 @@ pidfile_create (const char *filename)
|
||||
/*
|
||||
* Open a stdio file over the low-level one.
|
||||
*/
|
||||
if ((fd = fdopen (fildes, "w")) == NULL)
|
||||
{
|
||||
if ((fd = fdopen (fildes, "w")) == NULL) {
|
||||
fprintf (stderr,
|
||||
"%s: Could not write PID file %s: %s.",
|
||||
PACKAGE, filename, strerror (errno));
|
||||
|
48
src/vector.c
48
src/vector.c
@ -33,16 +33,14 @@
|
||||
* vector_s stores a pointer to the first vector (vector[0]) and a
|
||||
* count of the number of entries (or how long the vector is.)
|
||||
*/
|
||||
struct vectorentry_s
|
||||
{
|
||||
struct vectorentry_s {
|
||||
void *data;
|
||||
size_t len;
|
||||
|
||||
struct vectorentry_s *next;
|
||||
};
|
||||
|
||||
struct vector_s
|
||||
{
|
||||
struct vector_s {
|
||||
size_t num_entries;
|
||||
struct vectorentry_s *head;
|
||||
struct vectorentry_s *tail;
|
||||
@ -55,12 +53,11 @@ struct vector_s
|
||||
* A NULL is returned if memory could not be allocated for the
|
||||
* vector.
|
||||
*/
|
||||
vector_t
|
||||
vector_create (void)
|
||||
vector_t vector_create (void)
|
||||
{
|
||||
vector_t vector;
|
||||
|
||||
vector = (vector_t)safemalloc (sizeof (struct vector_s));
|
||||
vector = (vector_t) safemalloc (sizeof (struct vector_s));
|
||||
if (!vector)
|
||||
return NULL;
|
||||
|
||||
@ -76,8 +73,7 @@ vector_create (void)
|
||||
* Returns: 0 on success
|
||||
* negative if a NULL vector is supplied
|
||||
*/
|
||||
int
|
||||
vector_delete (vector_t vector)
|
||||
int vector_delete (vector_t vector)
|
||||
{
|
||||
struct vectorentry_s *ptr, *next;
|
||||
|
||||
@ -85,8 +81,7 @@ vector_delete (vector_t vector)
|
||||
return -EINVAL;
|
||||
|
||||
ptr = vector->head;
|
||||
while (ptr)
|
||||
{
|
||||
while (ptr) {
|
||||
next = ptr->next;
|
||||
safefree (ptr->data);
|
||||
safefree (ptr);
|
||||
@ -112,8 +107,7 @@ vector_delete (vector_t vector)
|
||||
#define INSERT_PREPEND 0
|
||||
#define INSERT_APPEND 1
|
||||
|
||||
static int
|
||||
vector_insert (vector_t vector, void *data, size_t len, int pos)
|
||||
static int vector_insert (vector_t vector, void *data, size_t len, int pos)
|
||||
{
|
||||
struct vectorentry_s *entry;
|
||||
|
||||
@ -121,13 +115,13 @@ vector_insert (vector_t vector, void *data, size_t len, int pos)
|
||||
(pos != INSERT_PREPEND && pos != INSERT_APPEND))
|
||||
return -EINVAL;
|
||||
|
||||
entry = (struct vectorentry_s *)safemalloc (sizeof (struct vectorentry_s));
|
||||
entry =
|
||||
(struct vectorentry_s *) safemalloc (sizeof (struct vectorentry_s));
|
||||
if (!entry)
|
||||
return -ENOMEM;
|
||||
|
||||
entry->data = safemalloc (len);
|
||||
if (!entry->data)
|
||||
{
|
||||
if (!entry->data) {
|
||||
safefree (entry);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -139,14 +133,11 @@ vector_insert (vector_t vector, void *data, size_t len, int pos)
|
||||
/* If there is no head or tail, create them */
|
||||
if (!vector->head && !vector->tail)
|
||||
vector->head = vector->tail = entry;
|
||||
else if (pos == 0)
|
||||
{
|
||||
else if (pos == 0) {
|
||||
/* prepend the entry */
|
||||
entry->next = vector->head;
|
||||
vector->head = entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* append the entry */
|
||||
vector->tail->next = entry;
|
||||
vector->tail = entry;
|
||||
@ -162,14 +153,12 @@ vector_insert (vector_t vector, void *data, size_t len, int pos)
|
||||
* can see they simply call the vector_insert() function with appropriate
|
||||
* arguments.
|
||||
*/
|
||||
int
|
||||
vector_append (vector_t vector, void *data, size_t len)
|
||||
int vector_append (vector_t vector, void *data, size_t len)
|
||||
{
|
||||
return vector_insert (vector, data, len, INSERT_APPEND);
|
||||
}
|
||||
|
||||
int
|
||||
vector_prepend (vector_t vector, void *data, size_t len)
|
||||
int vector_prepend (vector_t vector, void *data, size_t len)
|
||||
{
|
||||
return vector_insert (vector, data, len, INSERT_PREPEND);
|
||||
}
|
||||
@ -181,8 +170,7 @@ vector_prepend (vector_t vector, void *data, size_t len)
|
||||
* Returns: negative upon an error
|
||||
* length of data if position is valid
|
||||
*/
|
||||
void *
|
||||
vector_getentry (vector_t vector, size_t pos, size_t * size)
|
||||
void *vector_getentry (vector_t vector, size_t pos, size_t * size)
|
||||
{
|
||||
struct vectorentry_s *ptr;
|
||||
size_t loc;
|
||||
@ -193,8 +181,7 @@ vector_getentry (vector_t vector, size_t pos, size_t * size)
|
||||
loc = 0;
|
||||
ptr = vector->head;
|
||||
|
||||
while (loc != pos)
|
||||
{
|
||||
while (loc != pos) {
|
||||
ptr = ptr->next;
|
||||
loc++;
|
||||
}
|
||||
@ -211,8 +198,7 @@ vector_getentry (vector_t vector, size_t pos, size_t * size)
|
||||
* Returns: negative if vector is not valid
|
||||
* positive length of vector otherwise
|
||||
*/
|
||||
ssize_t
|
||||
vector_length (vector_t vector)
|
||||
ssize_t vector_length (vector_t vector)
|
||||
{
|
||||
if (!vector)
|
||||
return -EINVAL;
|
||||
|
14
src/vector.h
14
src/vector.h
@ -26,14 +26,14 @@
|
||||
* vector. Sure, it's a pointer, but the struct is hidden in the C file.
|
||||
* So, just use the vector_t like it's a cookie. :)
|
||||
*/
|
||||
typedef struct vector_s *vector_t;
|
||||
typedef struct vector_s *vector_t;
|
||||
|
||||
/*
|
||||
* vector_create() takes no arguments.
|
||||
* vector_delete() is self explanatory.
|
||||
*/
|
||||
extern vector_t vector_create (void);
|
||||
extern int vector_delete (vector_t vector);
|
||||
extern vector_t vector_create (void);
|
||||
extern int vector_delete (vector_t vector);
|
||||
|
||||
/*
|
||||
* When you insert a piece of data into the vector, the data will be
|
||||
@ -43,8 +43,8 @@
|
||||
* Returns: negative on error
|
||||
* 0 upon successful insert.
|
||||
*/
|
||||
extern int vector_append (vector_t vector, void *data, size_t len);
|
||||
extern int vector_prepend (vector_t vector, void *data, size_t len);
|
||||
extern int vector_append (vector_t vector, void *data, size_t len);
|
||||
extern int vector_prepend (vector_t vector, void *data, size_t len);
|
||||
|
||||
/*
|
||||
* A pointer to the data at position "pos" (zero based) is returned and the
|
||||
@ -62,7 +62,7 @@
|
||||
* Returns: NULL on error
|
||||
* valid pointer to data
|
||||
*/
|
||||
extern void *vector_getentry (vector_t vector, size_t pos, size_t * size);
|
||||
extern void *vector_getentry (vector_t vector, size_t pos, size_t * size);
|
||||
|
||||
/*
|
||||
* Returns the number of enteries (or the length) of the vector.
|
||||
@ -70,6 +70,6 @@
|
||||
* Returns: negative if vector is not valid
|
||||
* positive length of vector otherwise
|
||||
*/
|
||||
extern ssize_t vector_length (vector_t vector);
|
||||
extern ssize_t vector_length (vector_t vector);
|
||||
|
||||
#endif /* _VECTOR_H */
|
||||
|
Loading…
Reference in New Issue
Block a user