-- {
-- *--p = ':';
-- log_error(LOG_LEVEL_FATAL, "invalid bind port spec %s", config->haddr);
-- /* Never get here - LOG_LEVEL_FATAL causes program exit */
-- }
-- if (*config->haddr == '\0')
-- {
-- config->haddr = NULL;
-- }
-+ /* No listen-address set. The default is localhost on port 8118, on IPv4
-+ and (if INET6 is defined) IPv6.
-+ */
-+ struct bind_spec *bs;
-+#ifdef INET6
-+ config->hspecs = calloc(2,sizeof(struct bind_spec));
-+ if (config->hspecs == NULL)
-+ fail_load_config_memory(fs,config);
-+ config->hspecs_size=2;
-+ config->hspecs_occupied=1;
-+ bs = &config->hspecs[0];
-+ bs->haddr = strdup("::1");
-+ bs->hport = strdup("8118");
-+ bs->pf = PF_UNSPEC;
-+#else
-+ config->hspecs = calloc(1,sizeof(struct bind_spec));
-+ if (config->hspecs == NULL)
-+ fail_load_config_memory(fs,config);
-+ config->hspecs_size=1;
-+ config->hspecs_occupied=0;
-+#endif
-+ bs = &config->hspecs[config->hspecs_occupied++];
-+ bs->haddr = strdup("127.0.0.1");
-+ bs->hport = strdup("8118");
-+ bs->pf = PF_UNSPEC;
- }
-
- /*
-@@ -1586,31 +1596,29 @@
- struct configuration_spec * oldcfg = (struct configuration_spec *)
- current_configfile->f;
- /*
-- * Check if config->haddr,hport == oldcfg->haddr,hport
-- *
-- * The following could be written more compactly as a single,
-- * (unreadably long) if statement.
-+ * Check if the listening addresses have changed
- */
- config->need_bind = 0;
-- if (config->hport != oldcfg->hport)
-- {
-- config->need_bind = 1;
-- }
-- else if (config->haddr == NULL)
-+ if (config -> hspecs_occupied == oldcfg -> hspecs_occupied)
- {
-- if (oldcfg->haddr != NULL)
-+ int bs_index;
-+ struct bind_spec *hspec;
-+ struct bind_spec *oldhspec;
-+ hspec = config -> hspecs;
-+ oldhspec = oldcfg -> hspecs;
-+ for(bs_index = 0; bs_index < oldcfg->hspecs_occupied; ++bs_index)
- {
-- config->need_bind = 1;
-+ if (strcmp(hspec[bs_index].haddr,oldhspec[bs_index].haddr) != 0
-+ || strcmp(hspec[bs_index].hport,oldhspec[bs_index].hport) != 0
-+ || hspec[bs_index].pf != hspec[bs_index].pf)
-+ {
-+ config -> need_bind = 1;
-+ break;
-+ }
- }
- }
-- else if (oldcfg->haddr == NULL)
-- {
-- config->need_bind = 1;
-- }
-- else if (0 != strcmp(config->haddr, oldcfg->haddr))
-- {
-- config->need_bind = 1;
-- }
-+ else
-+ config-> need_bind = 1;
-
- current_configfile->unloader = unload_configfile;
- }
-diff -urNad privoxy~/loaders.c privoxy/loaders.c
---- privoxy~/loaders.c
-+++ privoxy/loaders.c
-@@ -11,6 +11,9 @@
- * Copyright : Written by and Copyright (C) 2001 the SourceForge
- * Privoxy team. http://www.privoxy.org/
- *
-+ * Modified by Lionel Elie Mamane <lionel@mamane.lu>
-+ * for IPv6 support on 8 December 2002, 24 January 2003.
-+ *
- * Based on the Internet Junkbuster originally written
- * by and Copyright (C) 1997 Anonymous Coders and
- * Junkbusters Corporation. http://www.junkbusters.com
-@@ -465,6 +468,7 @@
-
- freez(csp->ip_addr_str);
- freez(csp->my_ip_addr_str);
-+ freez(csp->my_port_str);
- freez(csp->my_hostname);
- freez(csp->x_forwarded);
- freez(csp->iob->buf);
-diff -urNad privoxy~/miscutil.h privoxy/miscutil.h
---- privoxy~/miscutil.h
-+++ privoxy/miscutil.h
-@@ -162,6 +162,15 @@
-
- #include "project.h"
-
-+/* Fix a problem with Solaris. There should be no effect on other
-+ * platforms.
-+ * Solaris's isspace() is a macro which uses it's argument directly
-+ * as an array index. Therefore we need to make sure that high-bit
-+ * characters generate +ve values, and ideally we also want to make
-+ * the argument match the declared parameter type of "int".
-+ */
-+#define ijb_isdigit(__X) isdigit((int)(unsigned char)(__X))
-+
- #if defined(__cplusplus)
- extern "C" {
- #endif
-diff -urNad privoxy~/parsers.c privoxy/parsers.c
---- privoxy~/parsers.c
-+++ privoxy/parsers.c
-@@ -16,6 +16,9 @@
- * Copyright : Written by and Copyright (C) 2001 the SourceForge
- * Privoxy team. http://www.privoxy.org/
- *
-+ * Modified by Lionel Elie Mamane <lionel@mamane.lu>
-+ * for IPv6 support on 24 January 2003.
-+ *
- * Based on the Internet Junkbuster originally written
- * by and Copyright (C) 1997 Anonymous Coders and
- * Junkbusters Corporation. http://www.junkbusters.com
-@@ -1951,6 +1954,167 @@
- return JB_ERR_OK;
- }
-
-+/*********************************************************************
-+ *
-+ * Function : parse_pf_ip_netmask
-+ *
-+ * Description : Parse an IPv{4,6} litteral or hostname
-+ * with optional port and optional explicit family
-+ * and optional netmask
-+ *
-+ * Parameters :
-+ * 0 : string = the string to parse
-+ * 1 : host = Is set to point to the hostname or IP literal
-+ * part
-+ * 2 : port = Is set to point to the port part,
-+ * or NULL if no port in string
-+ * 3 : pf = pointer used to return the address family
-+ * pf is a value-result argument:
-+ * If it is set to -1, then parse_pf_ip will set it
-+ * to the address family of the pf_ip string
-+ * else, it won't touch it, and fail if the two
-+ * cannot match
-+ * 4 : pointer used to return the mask length
-+ * Set to -1 if no mask
-+ *
-+ * Returns : 0 on success
-+ *
-+ *********************************************************************/
-+int parse_pf_ip_netmask(char *string, char **host, char **port, int *pf, int *masklength)
-+{
-+ int i;
-+ char *p;
-+
-+ *masklength = -1;
-+
-+ if ((p = strchr(string, '/')) != NULL)
-+ {
-+ *p++ = '\0';
-+
-+ if (ijb_isdigit(*p) == 0)
-+ {
-+ return -1;
-+ }
-+ i = atoi(p);
-+ if ( i < 0 )
-+ return -1;
-+ *masklength = i;
-+ }
-+
-+ return parse_pf_ip(string, host, port, pf);
-+}
-+
-+/*********************************************************************
-+ *
-+ * Function : parse_pf_ip
-+ *
-+ * Description : Parse an IPv{4,6} litteral or hostname
-+ * with optional port and optional explicit family
-+ *
-+ * Parameters :
-+ * 0 : string = the string to parse
-+ * 1 : host = Is set to point to the hostname or IP literal
-+ * part
-+ * 2 : port = Is set to point to the port part,
-+ * or NULL if no port in string
-+ * 3 : pf = pointer used to return the address family
-+ * pf is a value-result argument:
-+ * If it is set to -1, then parse_pf_ip will set it
-+ * to the address family of the pf_ip string
-+ * else, it won't touch it, and fail if the two
-+ * cannot match
-+ *
-+ * Returns : 0 on success
-+ *
-+ *********************************************************************/
-+int parse_pf_ip(char *string, char **host, char **port, int *pf)
-+{
-+ if (pf != NULL && *pf == -1)
-+ *pf = PF_UNSPEC;
-+
-+ /* See if we want to override the default protocol family */
-+ if (strncmpic(string, "ipv4:", 5) == 0)
-+ {
-+ string += 5;
-+ if (pf!=NULL)
-+ {
-+ if(*pf==PF_INET || *pf==PF_UNSPEC)
-+ *pf = AF_INET;
-+ else
-+ {
-+ log_error(LOG_LEVEL_ERROR,"%s","IPv4 address found where other awaited");
-+ return -2;
-+ }
-+ }
-+ }
-+ else if (strncmpic(string, "ipv6:", 5) == 0)
-+ {
-+#ifdef INET6
-+ string += 5;
-+ if(*pf==PF_INET6 || *pf==PF_UNSPEC)
-+ *pf = AF_INET6;
-+ else
-+ {
-+ log_error(LOG_LEVEL_ERROR,"%s","IPv6 address found where other awaited");
-+ return -2;
-+ }
-+#else
-+ log_error(LOG_LEVEL_ERROR,"%s","This privoxy hasn't IPv6 support");
-+ return -1;
-+#endif
-+ }
-+ return parse_ip(string, host, port);
-+}
-+
-+/*********************************************************************
-+ *
-+ * Function : parse_ip
-+ *
-+ * Description : Parse an IPv{4,6} litteral or hostname
-+ * with optional port
-+ *
-+ * Parameters :
-+ * 0 : string = the string to parse
-+ * 1 : host = Is set to point to the hostname or IP literal
-+ * part
-+ * 2 : port = Is set to point to the port part,
-+ * or NULL if no port in string
-+ * Returns : 0 on success
-+ *
-+ *********************************************************************/
-+int parse_ip(char *string, char **host, char **port)
-+{
-+ char *p;
-+ int skip;
-+
-+ /* allow IPv6 address literal: [numbers:with:colons]:port/mask */
-+ if (string[0] == '[' && (p = strchr(string, ']')))
-+ {
-+ *p++ = '\0';
-+ skip = 1;
-+ }
-+ else
-+ {
-+ p = string;
-+ skip = 0;
-+ }
-+
-+ if (host != NULL)
-+ *host = string + skip;
-+
-+ for(;*p != '\0'; ++p)
-+ {
-+ if (*p == ':')