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