Slightly reword the announcement blurb and add line breaks
[privoxy.git] / loadcfg.c
index ac1675b..a5bc55d 100644 (file)
--- a/loadcfg.c
+++ b/loadcfg.c
@@ -1,4 +1,4 @@
-const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.122 2012/03/04 11:47:21 fabiankeil Exp $";
+const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.134 2012/10/21 12:53:33 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/loadcfg.c,v $
@@ -123,6 +123,7 @@ static struct file_list *current_configfile = NULL;
 #define hash_admin_address               4112573064U /* "admin-address" */
 #define hash_allow_cgi_request_crunching  258915987U /* "allow-cgi-request-crunching" */
 #define hash_buffer_limit                1881726070U /* "buffer-limit */
+#define hash_client_header_order         2701453514U /* "client-header-order" */
 #define hash_compression_level           2464423563U /* "compression-level" */
 #define hash_confdir                        1978389U /* "confdir" */
 #define hash_connection_sharing          1348841265U /* "connection-sharing" */
@@ -139,6 +140,7 @@ static struct file_list *current_configfile = NULL;
 #define hash_forward_socks4              3963965521U /* "forward-socks4" */
 #define hash_forward_socks4a             2639958518U /* "forward-socks4a" */
 #define hash_forward_socks5              3963965522U /* "forward-socks5" */
+#define hash_forward_socks5t             2639958542U /* "forward-socks5t" */
 #define hash_forwarded_connect_retries    101465292U /* "forwarded-connect-retries" */
 #define hash_handle_as_empty_returns_ok  1444873247U /* "handle-as-empty-doc-returns-ok" */
 #define hash_hostname                      10308071U /* "hostname" */
@@ -154,6 +156,7 @@ static struct file_list *current_configfile = NULL;
 #define hash_split_large_cgi_forms        671658948U /* "split-large-cgi-forms" */
 #define hash_suppress_blocklists         1948693308U /* "suppress-blocklists" */
 #define hash_templdir                      11067889U /* "templdir" */
+#define hash_tolerate_pipelining         1360286620U /* "tolerate-pipelining" */
 #define hash_toggle                          447966U /* "toggle" */
 #define hash_trust_info_url               430331967U /* "trust-info-url" */
 #define hash_trustfile                     56494766U /* "trustfile" */
@@ -233,6 +236,8 @@ static void unload_configfile (void * data)
       freez(config->re_filterfile[i]);
    }
 
+   list_remove_all(config->ordered_client_headers);
+
    freez(config->admin_address);
    freez(config->proxy_info_url);
    freez(config->proxy_args);
@@ -316,6 +321,76 @@ static int parse_toggle_state(const char *name, const char *value)
 }
 
 
+/*********************************************************************
+ *
+ * Function    :  parse_client_header_order
+ *
+ * Description :  Parse the value of the header-order directive
+ *
+ * Parameters  :
+ *          1  :  ordered_header_list:  List to insert the ordered
+ *                                      headers into.
+ *          2  :  ordered_headers:  The ordered header names separated
+ *                                  by spaces or tabs.
+ *
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+static void parse_client_header_order(struct list *ordered_header_list, const char *ordered_headers)
+{
+   char *original_headers_copy;
+   char **vector;
+   size_t max_segments;
+   int number_of_headers;
+   int i;
+
+   assert(ordered_header_list != NULL);
+   assert(ordered_headers != NULL);
+
+   if (ordered_headers == NULL)
+   {
+      log_error(LOG_LEVEL_FATAL, "header-order used without argument");
+   }
+
+   /*
+    * XXX: This estimate is guaranteed to be high enough as we
+    *      let ssplit() ignore empty fields, but also a bit wasteful.
+    *      The same hack is used in get_last_url() so it looks like
+    *      a real solution is needed.
+    */
+   max_segments = strlen(ordered_headers) / 2;
+   if (max_segments == 0)
+   {
+      max_segments = 1;
+   }
+   vector = malloc_or_die(max_segments * sizeof(char *));
+
+   original_headers_copy = strdup_or_die(ordered_headers);
+
+   number_of_headers = ssplit(original_headers_copy, "\t ", vector, max_segments);
+   if (number_of_headers == -1)
+   {
+      log_error(LOG_LEVEL_FATAL, "Failed to split ordered headers");
+   }
+
+   for (i = 0; i < number_of_headers; i++)
+   {
+      if (JB_ERR_OK != enlist(ordered_header_list, vector[i]))
+      {
+         log_error(LOG_LEVEL_FATAL,
+            "Failed to enlist ordered header: %s", vector[i]);
+      }
+   }
+
+   freez(vector);
+   freez(original_headers_copy);
+
+   return;
+
+}
+
+
 /*********************************************************************
  *
  * Function    :  load_config
@@ -411,6 +486,7 @@ struct configuration_spec * load_config(void)
     */
    config->compression_level         = 1;
 #endif
+   config->feature_flags            &= ~RUNTIME_FEATURE_TOLERATE_PIPELINING;
 
    configfp = fopen(configfile, "r");
    if (NULL == configfp)
@@ -466,9 +542,9 @@ struct configuration_spec * load_config(void)
       /* Make sure the command field is lower case */
       for (p = cmd; *p; p++)
       {
-         if (ijb_isupper(*p))
+         if (privoxy_isupper(*p))
          {
-            *p = (char)ijb_tolower(*p);
+            *p = (char)privoxy_tolower(*p);
          }
       }
 
@@ -539,12 +615,20 @@ struct configuration_spec * load_config(void)
             config->buffer_limit = (size_t)(1024 * atoi(arg));
             break;
 
+/* *************************************************************************
+ * client-header-order header-1 header-2 ... header-n
+ * *************************************************************************/
+         case hash_client_header_order:
+            list_remove_all(config->ordered_client_headers);
+            parse_client_header_order(config->ordered_client_headers, arg);
+            break;
+
 /* *************************************************************************
  * confdir directory-name
  * *************************************************************************/
          case hash_confdir :
             freez(config->confdir);
-            config->confdir = make_path( NULL, arg);
+            config->confdir = make_path(NULL, arg);
             break;
 
 /* *************************************************************************
@@ -605,7 +689,7 @@ struct configuration_spec * load_config(void)
             if (*arg != '\0')
             {
                int timeout = atoi(arg);
-               if (0 < timeout)
+               if (0 <= timeout)
                {
                   config->default_server_timeout = (unsigned int)timeout;
                }
@@ -624,7 +708,7 @@ struct configuration_spec * load_config(void)
 #ifdef FEATURE_ACL
          case hash_deny_access:
             strlcpy(tmp, arg, sizeof(tmp));
-            vec_count = ssplit(tmp, " \t", vec, SZ(vec), 1, 1);
+            vec_count = ssplit(tmp, " \t", vec, SZ(vec));
 
             if ((vec_count != 1) && (vec_count != 2))
             {
@@ -809,7 +893,7 @@ struct configuration_spec * load_config(void)
  * *************************************************************************/
          case hash_forward:
             strlcpy(tmp, arg, sizeof(tmp));
-            vec_count = ssplit(tmp, " \t", vec, SZ(vec), 1, 1);
+            vec_count = ssplit(tmp, " \t", vec, SZ(vec));
 
             if (vec_count != 2)
             {
@@ -864,7 +948,7 @@ struct configuration_spec * load_config(void)
  * *************************************************************************/
          case hash_forward_socks4:
             strlcpy(tmp, arg, sizeof(tmp));
-            vec_count = ssplit(tmp, " \t", vec, SZ(vec), 1, 1);
+            vec_count = ssplit(tmp, " \t", vec, SZ(vec));
 
             if (vec_count != 3)
             {
@@ -930,8 +1014,9 @@ struct configuration_spec * load_config(void)
  * *************************************************************************/
          case hash_forward_socks4a:
          case hash_forward_socks5:
+         case hash_forward_socks5t:
             strlcpy(tmp, arg, sizeof(tmp));
-            vec_count = ssplit(tmp, " \t", vec, SZ(vec), 1, 1);
+            vec_count = ssplit(tmp, " \t", vec, SZ(vec));
 
             if (vec_count != 3)
             {
@@ -956,10 +1041,15 @@ struct configuration_spec * load_config(void)
             {
                cur_fwd->type = SOCKS_4A;
             }
-            else
+            else if (directive_hash == hash_forward_socks5)
             {
                cur_fwd->type = SOCKS_5;
             }
+            else
+            {
+               assert(directive_hash == hash_forward_socks5t);
+               cur_fwd->type = SOCKS_5T;
+            }
 
             /* Save the URL pattern */
             if (create_url_spec(cur_fwd->url, vec[0]))
@@ -1121,7 +1211,7 @@ struct configuration_spec * load_config(void)
 #ifdef FEATURE_ACL
          case hash_permit_access:
             strlcpy(tmp, arg, sizeof(tmp));
-            vec_count = ssplit(tmp, " \t", vec, SZ(vec), 1, 1);
+            vec_count = ssplit(tmp, " \t", vec, SZ(vec));
 
             if ((vec_count != 1) && (vec_count != 2))
             {
@@ -1220,7 +1310,7 @@ struct configuration_spec * load_config(void)
             if (*arg != '\0')
             {
                int socket_timeout = atoi(arg);
-               if (0 < socket_timeout)
+               if (0 <= socket_timeout)
                {
                   config->socket_timeout = socket_timeout;
                }
@@ -1254,12 +1344,26 @@ struct configuration_spec * load_config(void)
             config->templdir = make_path(NULL, arg);
             break;
 
+/* *************************************************************************
+ * tolerate-pipelining (0|1)
+ * *************************************************************************/
+         case hash_tolerate_pipelining :
+            if (parse_toggle_state(cmd, arg) == 1)
+            {
+               config->feature_flags |= RUNTIME_FEATURE_TOLERATE_PIPELINING;
+            }
+            else
+            {
+               config->feature_flags &= ~RUNTIME_FEATURE_TOLERATE_PIPELINING;
+            }
+            break;
+
 /* *************************************************************************
  * toggle (0|1)
  * *************************************************************************/
 #ifdef FEATURE_TOGGLE
          case hash_toggle :
-            global_toggle_state = atoi(arg);
+            global_toggle_state = parse_toggle_state(cmd, arg);
             break;
 #endif /* def FEATURE_TOGGLE */
 
@@ -1319,21 +1423,21 @@ struct configuration_spec * load_config(void)
  * activity-animation (0|1)
  * *************************************************************************/
          case hash_activity_animation :
-            g_bShowActivityAnimation = atoi(arg);
+            g_bShowActivityAnimation = parse_toggle_state(cmd, arg);
             break;
 
 /* *************************************************************************
  *  close-button-minimizes (0|1)
  * *************************************************************************/
          case hash_close_button_minimizes :
-            g_bCloseHidesWindow = atoi(arg);
+            g_bCloseHidesWindow = parse_toggle_state(cmd, arg);
             break;
 
 /* *************************************************************************
  * log-buffer-size (0|1)
  * *************************************************************************/
          case hash_log_buffer_size :
-            g_bLimitBufferSize = atoi(arg);
+            g_bLimitBufferSize = parse_toggle_state(cmd, arg);
             break;
 
 /* *************************************************************************
@@ -1360,7 +1464,7 @@ struct configuration_spec * load_config(void)
  * log-highlight-messages (0|1)
  * *************************************************************************/
          case hash_log_highlight_messages :
-            g_bHighlightMessages = atoi(arg);
+            g_bHighlightMessages = parse_toggle_state(cmd, arg);
             break;
 
 /* *************************************************************************
@@ -1374,14 +1478,14 @@ struct configuration_spec * load_config(void)
  * log-messages (0|1)
  * *************************************************************************/
          case hash_log_messages :
-            g_bLogMessages = atoi(arg);
+            g_bLogMessages = parse_toggle_state(cmd, arg);
             break;
 
 /* *************************************************************************
  * show-on-task-bar (0|1)
  * *************************************************************************/
          case hash_show_on_task_bar :
-            g_bShowOnTaskBar = atoi(arg);
+            g_bShowOnTaskBar = parse_toggle_state(cmd, arg);
             break;
 
 #endif /* defined(_WIN32) && ! defined(_WIN_CONSOLE) */
@@ -1437,19 +1541,20 @@ struct configuration_spec * load_config(void)
              * error.  To change back to an error, just change log level
              * to LOG_LEVEL_FATAL.
              */
-            log_error(LOG_LEVEL_ERROR, "Ignoring unrecognized directive '%s' (%luul) in line %lu "
-                  "in configuration file (%s).",  buf, directive_hash, linenum, configfile);
+            log_error(LOG_LEVEL_ERROR, "Ignoring unrecognized directive "
+               "'%s' (%uU) in line %lu in configuration file (%s).",
+               buf, directive_hash, linenum, configfile);
             string_append(&config->proxy_args,
                " <strong class='warning'>Warning: Ignoring unrecognized directive:</strong>");
             break;
 
 /* *************************************************************************/
-      } /* end switch( hash_string(cmd) ) */
+      } /* end switch(hash_string(cmd)) */
 
       /* Save the argument for the show-status page. */
       savearg(cmd, arg, config);
       freez(buf);
-   } /* end while ( read_config_line(...) ) */
+   } /* end while (read_config_line(...)) */
 
    fclose(configfp);
 
@@ -1532,9 +1637,9 @@ struct configuration_spec * load_config(void)
    }
 #endif /* def FEATURE_TRUST */
 
-   if ( NULL == config->haddr[0] )
+   if (NULL == config->haddr[0])
    {
-      config->haddr[0] = strdup( HADDR_DEFAULT );
+      config->haddr[0] = strdup(HADDR_DEFAULT);
       if (NULL == config->haddr[0])
       {
          log_error(LOG_LEVEL_FATAL, "Out of memory while copying default listening address");
@@ -1708,7 +1813,7 @@ static void savearg(char *command, char *argument, struct configuration_spec * c
       return;
    }
 
-   if ( (NULL != argument) && ('\0' != *argument) )
+   if ((NULL != argument) && ('\0' != *argument))
    {
       s = html_encode(argument);
       if (NULL == s)