Update copyright year in win32_blurb[].
[privoxy.git] / actions.c
index 56706e4..d5c02c4 100644 (file)
--- a/actions.c
+++ b/actions.c
@@ -1,4 +1,4 @@
-const char actions_rcs[] = "$Id: actions.c,v 1.37 2007/03/11 15:56:12 fabiankeil Exp $";
+const char actions_rcs[] = "$Id: actions.c,v 1.42 2008/02/09 15:15:38 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/actions.c,v $
@@ -6,7 +6,7 @@ const char actions_rcs[] = "$Id: actions.c,v 1.37 2007/03/11 15:56:12 fabiankeil
  * Purpose     :  Declares functions to work with actions files
  *                Functions declared include: FIXME
  *
- * Copyright   :  Written by and Copyright (C) 2001-2007 the SourceForge
+ * Copyright   :  Written by and Copyright (C) 2001-2008 the SourceForge
  *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
@@ -33,6 +33,30 @@ const char actions_rcs[] = "$Id: actions.c,v 1.37 2007/03/11 15:56:12 fabiankeil
  *
  * Revisions   :
  *    $Log: actions.c,v $
+ *    Revision 1.42  2008/02/09 15:15:38  fabiankeil
+ *    List active and inactive actions in the show-url-info's
+ *    "Final results" section separately. Patch submitted by Lee
+ *    in #1830056, modified to list active actions first.
+ *
+ *    Revision 1.41  2008/01/28 20:17:40  fabiankeil
+ *    - Mark some parameters as immutable.
+ *    - Hide update_action_bits_for_all_tags() while it's unused.
+ *
+ *    Revision 1.40  2007/05/21 10:26:50  fabiankeil
+ *    - Use strlcpy() instead of strcpy().
+ *    - Provide a reason why loading the actions
+ *      file might have failed.
+ *
+ *    Revision 1.39  2007/04/17 18:21:45  fabiankeil
+ *    Split update_action_bits() into
+ *    update_action_bits_for_all_tags()
+ *    and update_action_bits_for_tag().
+ *
+ *    Revision 1.38  2007/04/15 16:39:20  fabiankeil
+ *    Introduce tags as alternative way to specify which
+ *    actions apply to a request. At the moment tags can be
+ *    created based on client and server headers.
+ *
  *    Revision 1.37  2007/03/11 15:56:12  fabiankeil
  *    Add kludge to log unknown aliases and actions before exiting.
  *
@@ -645,7 +669,25 @@ jb_err get_actions(char *line,
 
                   if ((value == NULL) || (*value == '\0'))
                   {
-                     return JB_ERR_PARSE;
+                     if (0 != strcmpic(action->name, "block"))
+                     {
+                        /*
+                         * XXX: Temporary backwards compatibility hack.
+                         */
+                        static int complaint_shown = 0;
+                        value = "No reason specified.";
+                        if (!complaint_shown)
+                        {
+                           log_error(LOG_LEVEL_ERROR, "At least one block "
+                              "without reason found. This may become a fatal "
+                              "error in future versions.");
+                           complaint_shown = 1;
+                        }
+                     }
+                     else
+                     {
+                        return JB_ERR_PARSE;
+                     }
                   }
                   /* FIXME: should validate option string here */
                   freez (cur_action->string[action->index]);
@@ -870,60 +912,92 @@ jb_err merge_current_action (struct current_action_spec *dest,
    return err;
 }
 
+#if 0
+/*********************************************************************
+ *
+ * Function    :  update_action_bits_for_all_tags
+ *
+ * Description :  Updates the action bits based on all matching tags.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     :  0 if no tag matched, or
+ *                1 otherwise
+ *
+ *********************************************************************/
+int update_action_bits_for_all_tags(struct client_state *csp)
+{
+   struct list_entry *tag;
+   int updated = 0;
+
+   for (tag = csp->tags->first; tag != NULL; tag = tag->next)
+   {
+      if (update_action_bits_for_tag(csp, tag->str))
+      {
+         updated = 1;
+      }
+   }
+
+   return updated;
+}
+#endif
 
 /*********************************************************************
  *
- * Function    :  update_action_bits
+ * Function    :  update_action_bits_for_tag
  *
- * Description :  Updates the action bits based on matching tags.
+ * Description :  Updates the action bits based on the action sections
+ *                whose tag patterns match a provided tag.
  *
  * Parameters  :
  *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  tag = The tag on which the update should be based on
  *
  * Returns     :  0 if no tag matched, or
  *                1 otherwise
  *
  *********************************************************************/
-int update_action_bits(struct client_state *csp)
+int update_action_bits_for_tag(struct client_state *csp, const char *tag)
 {
    struct file_list *fl;
    struct url_actions *b;
-   struct list_entry *tag;
+
    int updated = 0;
    int i;
 
-   /* Take each tag, */
-   for (tag = csp->tags->first; tag != NULL; tag = tag->next)
+   assert(tag);
+   assert(list_contains_item(csp->tags, tag));
+
+   /* Run through all action files, */
+   for (i = 0; i < MAX_AF_FILES; i++)
    {
-      /* run through all action files, */
-      for (i = 0; i < MAX_AF_FILES; i++)
+      if (((fl = csp->actions_list[i]) == NULL) || ((b = fl->f) == NULL))
       {
-         if (((fl = csp->actions_list[i]) == NULL) || ((b = fl->f) == NULL))
+         /* Skip empty files */
+         continue;
+      }
+
+      /* and through all the action patterns, */
+      for (b = b->next; NULL != b; b = b->next)
+      {
+         /* skip the URL patterns, */
+         if (NULL == b->url->tag_regex)
          {
-            /* Skip empty files */
             continue;
          }
-         /* and through all the action patterns, */
-         for (b = b->next; NULL != b; b = b->next)
-         {
-            /* skip the URL patterns, */
-            if (NULL == b->url->tag_regex)
-            {
-               continue;
-            }
 
-            /* and check if one of the tag patterns matches this tag, */
-            if (0 == regexec(b->url->tag_regex, tag->str, 0, NULL, 0))
+         /* and check if one of the tag patterns matches the tag, */
+         if (0 == regexec(b->url->tag_regex, tag, 0, NULL, 0))
+         {
+            /* if it does, update the action bit map, */
+            if (merge_current_action(csp->action, b->action))
             {
-               /* if it does, update the action bit map, */
-               if (merge_current_action(csp->action, b->action))
-               {
-                  log_error(LOG_LEVEL_ERROR,
-                     "Out of memorey while changing action bits");
-               }
-               /* and signal the change. */
-               updated = 1;
+               log_error(LOG_LEVEL_ERROR,
+                  "Out of memorey while changing action bits");
             }
+            /* and signal the change. */
+            updated = 1;
          }
       }
    }
@@ -1139,8 +1213,9 @@ static int load_one_actions_file(struct client_state *csp, int fileid)
    }
    if (!fs)
    {
-      log_error(LOG_LEVEL_FATAL, "can't load actions file '%s': error finding file: %E",
-                csp->config->actions_file[fileid]);
+      log_error(LOG_LEVEL_FATAL, "can't load actions file '%s': %E. "
+         "Note that beginning with Privoxy 3.0.7, actions files have to be specified "
+         "with their complete file names.", csp->config->actions_file[fileid]);
       return 1; /* never get here */
    }
 
@@ -1305,7 +1380,7 @@ static int load_one_actions_file(struct client_state *csp, int fileid)
             init_action(cur_action);
 
             /* trim { */
-            strcpy(actions_buf, buf + 1);
+            strlcpy(actions_buf, buf + 1, sizeof(actions_buf));
 
             /* check we have a trailing } and then trim it */
             end = actions_buf + strlen(actions_buf) - 1;
@@ -1447,7 +1522,7 @@ static int load_one_actions_file(struct client_state *csp, int fileid)
             return 1; /* never get here */
          }
 
-         strcpy(actions_buf, start);
+         strlcpy(actions_buf, start, sizeof(actions_buf));
 
          if (get_actions(actions_buf, alias_list, new_alias->action))
          {
@@ -1553,7 +1628,7 @@ static int load_one_actions_file(struct client_state *csp, int fileid)
  *                NULL on out-of-memory error.
  *
  *********************************************************************/
-char * actions_to_text(struct action_spec *action)
+char * actions_to_text(const struct action_spec *action)
 {
    unsigned mask = action->mask;
    unsigned add  = action->add;
@@ -1641,8 +1716,8 @@ char * actions_to_text(struct action_spec *action)
  *                NULL on out-of-memory error.
  *
  *********************************************************************/
-char * actions_to_html(struct client_state *csp,
-                       struct action_spec *action)
+char * actions_to_html(const struct client_state *csp,
+                       const struct action_spec *action)
 {
    unsigned mask = action->mask;
    unsigned add  = action->add;
@@ -1747,56 +1822,58 @@ char * actions_to_html(struct client_state *csp,
  *                NULL on out-of-memory error.
  *
  *********************************************************************/
-char *current_action_to_html(struct client_state *csp,
-                             struct current_action_spec *action)
+char *current_action_to_html(const struct client_state *csp,
+                             const struct current_action_spec *action)
 {
    unsigned long flags  = action->flags;
-   char * result = strdup("");
    struct list_entry * lst;
+   char *result   = strdup("");
+   char *active   = strdup("");
+   char *inactive = strdup("");
 
 #define DEFINE_ACTION_BOOL(__name, __bit)  \
    if (flags & __bit)                      \
    {                                       \
-      string_append(&result, "\n<br>+");   \
-      string_join(&result, add_help_link(__name, csp->config)); \
+      string_append(&active, "\n<br>+");   \
+      string_join(&active, add_help_link(__name, csp->config)); \
    }                                       \
    else                                    \
    {                                       \
-      string_append(&result, "\n<br>-");   \
-      string_join(&result, add_help_link(__name, csp->config)); \
+      string_append(&inactive, "\n<br>-"); \
+      string_join(&inactive, add_help_link(__name, csp->config)); \
    }
 
 #define DEFINE_ACTION_STRING(__name, __bit, __index)   \
    if (flags & __bit)                                  \
    {                                                   \
-      string_append(&result, "\n<br>+");               \
-      string_join(&result, add_help_link(__name, csp->config)); \
-      string_append(&result, "{");                     \
-      string_join(&result, html_encode(action->string[__index])); \
-      string_append(&result, "}");                     \
+      string_append(&active, "\n<br>+");               \
+      string_join(&active, add_help_link(__name, csp->config)); \
+      string_append(&active, "{");                     \
+      string_join(&active, html_encode(action->string[__index])); \
+      string_append(&active, "}");                     \
    }                                                   \
    else                                                \
    {                                                   \
-      string_append(&result, "\n<br>-");               \
-      string_join(&result, add_help_link(__name, csp->config)); \
+      string_append(&inactive, "\n<br>-");             \
+      string_join(&inactive, add_help_link(__name, csp->config)); \
    }
 
 #define DEFINE_ACTION_MULTI(__name, __index)           \
    lst = action->multi[__index]->first;                \
    if (lst == NULL)                                    \
    {                                                   \
-      string_append(&result, "\n<br>-");              \
-      string_join(&result, add_help_link(__name, csp->config)); \
+      string_append(&inactive, "\n<br>-");             \
+      string_join(&inactive, add_help_link(__name, csp->config)); \
    }                                                   \
    else                                                \
    {                                                   \
       while (lst)                                      \
       {                                                \
-         string_append(&result, "\n<br>+");            \
-         string_join(&result, add_help_link(__name, csp->config)); \
-         string_append(&result, "{");                  \
-         string_join(&result, html_encode(lst->str));  \
-         string_append(&result, "}");                  \
+         string_append(&active, "\n<br>+");            \
+         string_join(&active, add_help_link(__name, csp->config)); \
+         string_append(&active, "{");                  \
+         string_join(&active, html_encode(lst->str));  \
+         string_append(&active, "}");                  \
          lst = lst->next;                              \
       }                                                \
    }
@@ -1810,5 +1887,16 @@ char *current_action_to_html(struct client_state *csp,
 #undef DEFINE_ACTION_BOOL
 #undef DEFINE_ACTION_ALIAS
 
+   if (active != NULL)
+   {
+      string_append(&result, active);
+      freez(active);
+   }
+   string_append(&result, "\n<br>");
+   if (inactive != NULL)
+   {
+      string_append(&result, inactive);
+      freez(inactive);
+   }
    return result;
 }