Set the client-tag-lifetime default to 60 seconds
[privoxy.git] / loadcfg.c
index 0b68325..17cd85a 100644 (file)
--- a/loadcfg.c
+++ b/loadcfg.c
@@ -1,4 +1,4 @@
-const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.143 2015/08/12 10:38:02 fabiankeil Exp $";
+const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.148 2016/03/17 10:40:53 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/loadcfg.c,v $
@@ -8,7 +8,7 @@ const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.143 2015/08/12 10:38:02 fabiankei
  *                routine to load the configuration and the global
  *                variables it writes to.
  *
- * Copyright   :  Written by and Copyright (C) 2001-2014 the
+ * Copyright   :  Written by and Copyright (C) 2001-2016 the
  *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
@@ -124,6 +124,8 @@ static struct file_list *current_configfile = NULL;
 #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_client_specific_tag         3353703383U /* "client-specific-tag" */
+#define hash_client_tag_lifetime          647957580U /* "client-tag-lifetime" */
 #define hash_compression_level           2464423563U /* "compression-level" */
 #define hash_confdir                        1978389U /* "confdir" */
 #define hash_connection_sharing          1348841265U /* "connection-sharing" */
@@ -176,6 +178,9 @@ static struct file_list *current_configfile = NULL;
 
 
 static void savearg(char *command, char *argument, struct configuration_spec * config);
+#ifdef FEATURE_CLIENT_TAGS
+static void free_client_specific_tags(struct client_tag_spec *tag_list);
+#endif
 
 /*********************************************************************
  *
@@ -253,6 +258,10 @@ static void unload_configfile (void * data)
    list_remove_all(config->trust_info);
 #endif /* def FEATURE_TRUST */
 
+#ifdef FEATURE_CLIENT_TAGS
+   free_client_specific_tags(config->client_tags);
+#endif
+
    freez(config);
 }
 
@@ -281,6 +290,85 @@ void unload_current_config_file(void)
 #endif
 
 
+#ifdef FEATURE_CLIENT_TAGS
+/*********************************************************************
+ *
+ * Function    :  register_tag
+ *
+ * Description :  Registers a client-specific-tag and its description
+ *
+ * Parameters  :
+ *          1  :  config: The tag list
+ *          2  :  name:  The name of the client-specific-tag
+ *          3  :  description: The human-readable description for the tag
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+static void register_tag(struct client_tag_spec *tag_list,
+   const char *name, const char *description)
+{
+   struct client_tag_spec *new_tag;
+   struct client_tag_spec *last_tag;
+
+   last_tag = tag_list;
+   while (last_tag->next != NULL)
+   {
+      last_tag = last_tag->next;
+   }
+   if (last_tag->name == NULL)
+   {
+      /* First entry */
+      new_tag = last_tag;
+   }
+   else
+   {
+      new_tag = zalloc_or_die(sizeof(struct client_tag_spec));
+   }
+   new_tag->name = strdup_or_die(name);
+   new_tag->description = strdup_or_die(description);
+   if (new_tag != last_tag)
+   {
+      last_tag->next = new_tag;
+   }
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  free_client_specific_tags
+ *
+ * Description :  Frees client-specific tags and their descriptions
+ *
+ * Parameters  :
+ *          1  :  tag_list: The tag list to free
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+static void free_client_specific_tags(struct client_tag_spec *tag_list)
+{
+   struct client_tag_spec *this_tag;
+   struct client_tag_spec *next_tag;
+
+   next_tag = tag_list;
+   do
+   {
+      this_tag = next_tag;
+      next_tag = next_tag->next;
+
+      freez(this_tag->name);
+      freez(this_tag->description);
+
+      if (this_tag != tag_list)
+      {
+         freez(this_tag);
+      }
+   } while (next_tag != NULL);
+}
+#endif /* def FEATURE_CLIENT_TAGS */
+
+
 /*********************************************************************
  *
  * Function    :  parse_numeric_value
@@ -484,15 +572,7 @@ struct configuration_spec * load_config(void)
    global_toggle_state = 1;
 #endif /* def FEATURE_TOGGLE */
 
-   fs->f = config = (struct configuration_spec *)zalloc(sizeof(*config));
-
-   if (NULL == config)
-   {
-      freez(fs->filename);
-      freez(fs);
-      log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
-      return NULL;
-   }
+   fs->f = config = zalloc_or_die(sizeof(*config));
 
    /*
     * This is backwards from how it's usually done.
@@ -513,6 +593,7 @@ struct configuration_spec * load_config(void)
    config->usermanual                = strdup(USER_MANUAL_URL);
    config->proxy_args                = strdup("");
    config->forwarded_connect_retries = 0;
+   config->client_tag_lifetime       = 60;
    /*
     * 128 client sockets ought to be enough for everybody who can't
     * be bothered to read the documentation to figure out how to
@@ -675,6 +756,49 @@ struct configuration_spec * load_config(void)
             parse_client_header_order(config->ordered_client_headers, arg);
             break;
 
+/* *************************************************************************
+ * client-specific-tag tag-name description
+ * *************************************************************************/
+#ifdef FEATURE_CLIENT_TAGS
+         case hash_client_specific_tag:
+            {
+               char *name;
+               char *description;
+
+               name = arg;
+               description = strstr(arg, " ");
+               if (description == NULL)
+               {
+                  log_error(LOG_LEVEL_FATAL,
+                     "client-specific-tag '%s' lacks a description.", name);
+               }
+               *description = '\0';
+               description++;
+               register_tag(config->client_tags, name, description);
+            }
+            break;
+#endif /* def FEATURE_CLIENT_TAGS */
+
+/* *************************************************************************
+ * client-tag-lifetime ttl
+ * *************************************************************************/
+#ifdef FEATURE_CLIENT_TAGS
+         case hash_client_tag_lifetime:
+         {
+            int ttl = parse_numeric_value(cmd, arg);
+            if (0 <= ttl)
+            {
+               config->client_tag_lifetime = (unsigned)ttl;
+            }
+            else
+            {
+               log_error(LOG_LEVEL_FATAL,
+                  "client-tag-lifetime can't be negative.");
+            }
+            break;
+         }
+#endif /* def FEATURE_CLIENT_TAGS */
+
 /* *************************************************************************
  * confdir directory-name
  * *************************************************************************/
@@ -692,7 +816,7 @@ struct configuration_spec * load_config(void)
             int compression_level = parse_numeric_value(cmd, arg);
             if (-1 <= compression_level && compression_level <= 9)
             {
-               config->compression_level = compression_level;;
+               config->compression_level = compression_level;
             }
             else
             {
@@ -766,14 +890,7 @@ struct configuration_spec * load_config(void)
             }
 
             /* allocate a new node */
-            cur_acl = (struct access_control_list *) zalloc(sizeof(*cur_acl));
-
-            if (cur_acl == NULL)
-            {
-               log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
-               /* Never get here - LOG_LEVEL_FATAL causes program exit */
-               break;
-            }
+            cur_acl = zalloc_or_die(sizeof(*cur_acl));
             cur_acl->action = ACL_DENY;
 
             if (acl_addr(vec[0], cur_acl->src) < 0)
@@ -964,14 +1081,7 @@ struct configuration_spec * load_config(void)
             }
 
             /* allocate a new node */
-            cur_fwd = zalloc(sizeof(*cur_fwd));
-            if (cur_fwd == NULL)
-            {
-               log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
-               /* Never get here - LOG_LEVEL_FATAL causes program exit */
-               break;
-            }
-
+            cur_fwd = zalloc_or_die(sizeof(*cur_fwd));
             cur_fwd->type = SOCKS_NONE;
 
             /* Save the URL pattern */
@@ -1020,14 +1130,7 @@ struct configuration_spec * load_config(void)
             }
 
             /* allocate a new node */
-            cur_fwd = zalloc(sizeof(*cur_fwd));
-            if (cur_fwd == NULL)
-            {
-               log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
-               /* Never get here - LOG_LEVEL_FATAL causes program exit */
-               break;
-            }
-
+            cur_fwd = zalloc_or_die(sizeof(*cur_fwd));
             cur_fwd->type = SOCKS_4;
 
             /* Save the URL pattern */
@@ -1092,13 +1195,7 @@ struct configuration_spec * load_config(void)
             }
 
             /* allocate a new node */
-            cur_fwd = zalloc(sizeof(*cur_fwd));
-            if (cur_fwd == NULL)
-            {
-               log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
-               /* Never get here - LOG_LEVEL_FATAL causes program exit */
-               break;
-            }
+            cur_fwd = zalloc_or_die(sizeof(*cur_fwd));
 
             if (directive_hash == hash_forward_socks4a)
             {
@@ -1291,14 +1388,7 @@ struct configuration_spec * load_config(void)
             }
 
             /* allocate a new node */
-            cur_acl = (struct access_control_list *) zalloc(sizeof(*cur_acl));
-
-            if (cur_acl == NULL)
-            {
-               log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
-               /* Never get here - LOG_LEVEL_FATAL causes program exit */
-               break;
-            }
+            cur_acl = zalloc_or_die(sizeof(*cur_acl));
             cur_acl->action = ACL_PERMIT;
 
             if (acl_addr(vec[0], cur_acl->src) < 0)
@@ -1758,7 +1848,7 @@ struct configuration_spec * load_config(void)
     *
     * Need to set up a fake csp, so they can get to the config.
     */
-   fake_csp = (struct client_state *) zalloc (sizeof(*fake_csp));
+   fake_csp = zalloc_or_die(sizeof(*fake_csp));
    fake_csp->config = config;
 
    if (run_loader(fake_csp))