cgi_show_client_tags(): Fix a harmless 'dead store' warning
[privoxy.git] / cgisimple.c
index faa70da..562eeb6 100644 (file)
@@ -1,4 +1,4 @@
-const char cgisimple_rcs[] = "$Id: cgisimple.c,v 1.135 2016/03/04 13:22:22 fabiankeil Exp $";
+const char cgisimple_rcs[] = "$Id: cgisimple.c,v 1.149 2017/05/04 14:33:17 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/cgisimple.c,v $
@@ -6,7 +6,7 @@ const char cgisimple_rcs[] = "$Id: cgisimple.c,v 1.135 2016/03/04 13:22:22 fabia
  * Purpose     :  Simple CGIs to get information about Privoxy's
  *                status.
  *
- * Copyright   :  Written by and Copyright (C) 2001-2016 the
+ * Copyright   :  Written by and Copyright (C) 2001-2017 the
  *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
@@ -275,6 +275,49 @@ jb_err cgi_show_request(struct client_state *csp,
 
 
 #ifdef FEATURE_CLIENT_TAGS
+/*********************************************************************
+ *
+ * Function    :  cgi_create_client_tag_form
+ *
+ * Description :  Creates a HTML form to enable or disable a given
+ *                client tag.
+ *                XXX: Could use a template.
+ *
+ * Parameters  :
+ *          1  :  form = Buffer to fill with the generated form
+ *          2  :  size = Size of the form buffer
+ *          3  :  tag = Name of the tag this form should affect
+ *          4  :  toggle_state = Desired state after the button pressed 0
+ *          5  :  expires = Whether or not the tag should be enabled.
+ *                          Only checked if toggle_state is 1.
+ *
+ * Returns     :  void
+ *
+ *********************************************************************/
+static void cgi_create_client_tag_form(char *form, size_t size,
+   const char *tag, int toggle_state, int expires)
+{
+   char *button_name;
+
+   if (toggle_state == 1)
+   {
+      button_name = (expires == 1) ? "Enable" : "Enable temporarily";
+   }
+   else
+   {
+      assert(toggle_state == 0);
+      button_name = "Disable";
+   }
+
+   snprintf(form, size,
+      "<form method=\"GET\" action=\""CGI_PREFIX"toggle-client-tag\" style=\"display: inline\">\n"
+      " <input type=\"hidden\" name=\"tag\" value=\"%s\">\n"
+      " <input type=\"hidden\" name=\"toggle-state\" value=\"%u\">\n"
+      " <input type=\"hidden\" name=\"expires\" value=\"%u\">\n"
+      " <input type=\"submit\" value=\"%s\">\n"
+      "</form>", tag, toggle_state, !expires, button_name);
+}
+
 /*********************************************************************
  *
  * Function    :  cgi_show_client_tags
@@ -300,106 +343,169 @@ jb_err cgi_show_client_tags(struct client_state *csp,
    struct map *exports;
    struct client_tag_spec *this_tag;
    jb_err err = JB_ERR_OK;
-   const char *toggled_tag;
-   const char *toggle_state;
-   const char *tag_expires;
-   time_t time_to_live;
-   char *client_tags = strdup_or_die("");
+   char *client_tag_status;
    char buf[1000];
+   time_t refresh_delay;
 
    assert(csp);
    assert(rsp);
    assert(parameters);
 
-   if (NULL == (exports = default_exports(csp, "show-client-tags")))
+   if (NULL == (exports = default_exports(csp, "client-tags")))
    {
       return JB_ERR_MEMORY;
    }
-
-   toggled_tag = lookup(parameters, "tag");
-   if (*toggled_tag != '\0')
-   {
-      tag_expires = lookup(parameters, "expires");
-      if (*tag_expires == '0')
-      {
-         time_to_live = 0;
-      }
-      else
-      {
-         time_to_live = csp->config->client_tag_lifetime;
-      }
-      toggle_state = lookup(parameters, "toggle-state");
-      if (*toggle_state == '1')
-      {
-         enable_client_specific_tag(csp, toggled_tag, time_to_live);
-      }
-      else
-      {
-         disable_client_specific_tag(csp, toggled_tag);
-      }
-   }
+   assert(csp->client_address != NULL);
 
    this_tag = csp->config->client_tags;
    if (this_tag->name == NULL)
    {
-      if (!err) err = string_append(&client_tags, "<p>No tags available.</p>\n");
+      client_tag_status = strdup_or_die("<p>No tags available.</p>\n");
    }
    else
    {
-      if (!err)
-      {
-         err = string_append(&client_tags, "<table border=\"1\">\n"
-            "<tr><th>Tag name</th>\n"
-            "<th>Current state</th><th>Change state</th><th>Description</th></tr>\n");
-      }
+      client_tag_status = strdup_or_die("<table border=\"1\">\n"
+         "<tr><th>Tag name</th>\n"
+         "<th>Current state</th><th>Change state</th><th>Description</th></tr>\n");
       while ((this_tag != NULL) && (this_tag->name != NULL))
       {
          int tag_state;
 
          privoxy_mutex_lock(&client_tags_mutex);
-         tag_state = client_has_requested_tag(csp->ip_addr_str, this_tag->name);
+         tag_state = client_has_requested_tag(csp->client_address, this_tag->name);
          privoxy_mutex_unlock(&client_tags_mutex);
-         if (!err) err = string_append(&client_tags, "<tr><td>");
-         if (!err) err = string_append(&client_tags, this_tag->name);
-         if (!err) err = string_append(&client_tags, "</td><td>");
-         if (!err) err = string_append(&client_tags, tag_state == 1 ? "Enabled" : "Disabled");
-         snprintf(buf, sizeof(buf),
-            "</td><td><a href=\"/show-client-tags?tag=%s&toggle-state=%d&amp;expires=0\">%s</a>",
-            this_tag->name, !tag_state, tag_state == 1 ? "Disable" : "Enable");
-         if (!err) err = string_append(&client_tags, buf);
+         if (!err) err = string_append(&client_tag_status, "<tr><td>");
+         if (!err) err = string_append(&client_tag_status, this_tag->name);
+         if (!err) err = string_append(&client_tag_status, "</td><td>");
+         if (!err) err = string_append(&client_tag_status, tag_state == 1 ? "Enabled" : "Disabled");
+         if (!err) err = string_append(&client_tag_status, "</td><td>");
+         cgi_create_client_tag_form(buf, sizeof(buf), this_tag->name, !tag_state, 1);
+         if (!err) err = string_append(&client_tag_status, buf);
          if (tag_state == 0)
          {
-            snprintf(buf, sizeof(buf), ". <a href=\"/show-client-tags?"
-               "tag=%s&amp;toggle-state=1&amp;expires=1\">Enable temporarily</a>",
-               this_tag->name);
-            if (!err) err = string_append(&client_tags, buf);
+            cgi_create_client_tag_form(buf, sizeof(buf), this_tag->name, !tag_state, 0);
+            if (!err) err = string_append(&client_tag_status, buf);
          }
-         if (!err) err = string_append(&client_tags, "</td><td>");
-         if (!err) err = string_append(&client_tags, this_tag->description);
-         if (!err) err = string_append(&client_tags, "</td></tr>\n");
+         if (!err) err = string_append(&client_tag_status, "</td><td>");
+         if (!err) err = string_append(&client_tag_status, this_tag->description);
+         if (!err) err = string_append(&client_tag_status, "</td></tr>\n");
          if (err)
          {
-            free_map(exports);
-            return JB_ERR_MEMORY;
+            break;
          }
          this_tag = this_tag->next;
       }
-      if (!err) err = string_append(&client_tags, "</table>\n");
+      if (!err) err = string_append(&client_tag_status, "</table>\n");
+      if (err)
+      {
+         free_map(exports);
+         return JB_ERR_MEMORY;
+      }
+   }
+   refresh_delay = get_next_tag_timeout_for_client(csp->client_address);
+   if (refresh_delay != 0)
+   {
+      snprintf(buf, sizeof(buf), "%d", csp->config->client_tag_lifetime);
+      if (map(exports, "refresh-delay", 1, buf, 1))
+      {
+         free_map(exports);
+         return JB_ERR_MEMORY;
+      }
+   }
+   else
+   {
+      err = map_block_killer(exports, "tags-expire");
+      if (err != JB_ERR_OK)
+      {
+         return err;
+      }
    }
 
-   if (map(exports, "client-tags", 1, client_tags, 0))
+   if (map(exports, "client-tags", 1, client_tag_status, 0))
    {
       free_map(exports);
       return JB_ERR_MEMORY;
    }
 
-   if (map(exports, "client-ip-addr", 1, csp->ip_addr_str, 1))
+   if (map(exports, "client-ip-addr", 1, csp->client_address, 1))
    {
       free_map(exports);
       return JB_ERR_MEMORY;
    }
 
-   return template_fill_for_cgi(csp, "show-client-tags", exports, rsp);
+   return template_fill_for_cgi(csp, "client-tags", exports, rsp);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  cgi_toggle_client_tag
+ *
+ * Description :  Toggles a client tag and redirects to the show-tags
+ *                page
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  rsp = http_response data structure for output
+ *          3  :  parameters = map of cgi parameters
+ *
+ * CGI Parameters : none
+ *          1  :  tag = Name of the tag to enable or disable
+ *          2  :  toggle-state = How to toggle the tag (0/1)
+ *          3  :  expires = Set to 1 if the tag should be enabled
+ *                          temporarily, otherwise set to 0
+ *
+ * Returns     :  JB_ERR_OK on success
+ *                JB_ERR_MEMORY on out-of-memory error.
+ *
+ *********************************************************************/
+jb_err cgi_toggle_client_tag(struct client_state *csp,
+                             struct http_response *rsp,
+                             const struct map *parameters)
+{
+   const char *toggled_tag;
+   const char *toggle_state;
+   const char *tag_expires;
+   time_t time_to_live;
+
+   assert(csp);
+   assert(rsp);
+   assert(parameters);
+
+   toggled_tag = lookup(parameters, "tag");
+   if (*toggled_tag == '\0')
+   {
+      log_error(LOG_LEVEL_ERROR, "Received tag toggle request without tag");
+   }
+   else
+   {
+      tag_expires = lookup(parameters, "expires");
+      if (*tag_expires == '0')
+      {
+         time_to_live = 0;
+      }
+      else
+      {
+         time_to_live = csp->config->client_tag_lifetime;
+      }
+      toggle_state = lookup(parameters, "toggle-state");
+      if (*toggle_state == '1')
+      {
+         enable_client_specific_tag(csp, toggled_tag, time_to_live);
+      }
+      else
+      {
+         disable_client_specific_tag(csp, toggled_tag);
+      }
+   }
+   rsp->status = strdup_or_die("302 Done dealing with toggle request");
+   if (enlist_unique_header(rsp->headers,
+         "Location", CGI_PREFIX "client-tags"))
+   {
+         return JB_ERR_MEMORY;
+   }
+   return JB_ERR_OK;
+
 }
 #endif /* def FEATURE_CLIENT_TAGS */
 
@@ -1675,6 +1781,14 @@ static jb_err show_defines(struct map *exports)
    };
 
    static const struct feature features[] = {
+      {
+         "FEATURE_64_BIT_TIME_T",
+#if (SIZEOF_TIME_T == 8)
+         1,
+#else
+         0,
+#endif
+      },
       {
          "FEATURE_ACCEPT_FILTER",
 #ifdef FEATURE_ACCEPT_FILTER
@@ -1729,6 +1843,14 @@ static jb_err show_defines(struct map *exports)
          1,
 #else
          0,
+#endif
+      },
+      {
+         "FEATURE_EXTERNAL_FILTERS",
+#ifdef FEATURE_EXTERNAL_FILTERS
+         1,
+#else
+         0,
 #endif
       },
       {
@@ -1761,14 +1883,6 @@ static jb_err show_defines(struct map *exports)
          1,
 #else
          0,
-#endif
-      },
-      {
-         "FEATURE_IMAGE_DETECT_MSIE",
-#ifdef FEATURE_IMAGE_DETECT_MSIE
-         1,
-#else
-         0,
 #endif
       },
       {
@@ -1902,9 +2016,6 @@ static char *show_rcs(void)
 #endif /* def FEATURE_CGI_EDIT_ACTIONS */
    SHOW_RCS(cgisimple_h_rcs)
    SHOW_RCS(cgisimple_rcs)
-#ifdef __MINGW32__
-   SHOW_RCS(cygwin_h_rcs)
-#endif
    SHOW_RCS(deanimate_h_rcs)
    SHOW_RCS(deanimate_rcs)
    SHOW_RCS(encode_h_rcs)