- Adding Doxygen-style comments to structures and #defines.
[privoxy.git] / cgiedit.c
index 55499c8..348feb0 100644 (file)
--- a/cgiedit.c
+++ b/cgiedit.c
@@ -1,4 +1,4 @@
-const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.32 2002/04/19 16:55:31 jongfoster Exp $";
+const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.38 2002/05/03 23:00:38 jongfoster Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/cgiedit.c,v $
@@ -42,6 +42,33 @@ const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.32 2002/04/19 16:55:31 jongfoster
  *
  * Revisions   :
  *    $Log: cgiedit.c,v $
+ *    Revision 1.38  2002/05/03 23:00:38  jongfoster
+ *    Support for templates for "standard actions" buttons.
+ *    See bug #549871
+ *
+ *    Revision 1.37  2002/04/30 11:14:52  oes
+ *    Made csp the first parameter in *action_to_html
+ *
+ *    Revision 1.36  2002/04/26 21:53:30  jongfoster
+ *    Fixing a memory leak.  (Near, but not caused by, my earlier commit).
+ *
+ *    Revision 1.35  2002/04/26 21:50:02  jongfoster
+ *    Honouring default exports in edit-actions-for-url-filter template.
+ *
+ *    Revision 1.34  2002/04/26 12:54:17  oes
+ *    Adaptions to changes in actions.c
+ *
+ *    Revision 1.33  2002/04/24 02:17:47  oes
+ *     - Moved get_char_param, get_string_param and get_number_param to cgi.c
+ *     - Comments
+ *     - Activated Jon's code for editing multiple AFs
+ *     - cgi_edit_list_actions now provides context-sensitive
+ *       help, looks up all action sets from standard.action and
+ *       makes buttons for them in the catchall section
+ *     - cgi_edit_action_submit now honors a p parameter, looks up
+ *       the corresponding action set, and sets the catchall pattern's
+ *       actions accordingly.
+ *
  *    Revision 1.32  2002/04/19 16:55:31  jongfoster
  *    Fixing newline problems.  If we do our own text file newline
  *    mangling, we don't want the library to do any, so we need to
@@ -250,23 +277,49 @@ const char cgiedit_h_rcs[] = CGIEDIT_H_VERSION;
 
 #ifdef FEATURE_CGI_EDIT_ACTIONS
 
+/**
+ * A line in an editable_file.
+ */
 struct file_line
 {
+   /** Next entry in the linked list */
    struct file_line * next;
+   
+   /** The raw data, to write out if this line is unmodified. */
    char * raw;
+   
+   /** Comments and/or whitespace to put before this line if it's modified
+       and then written out. */
    char * prefix;
+
+   /** The actual data, as a string.  Line continuation and comment removal
+       are performed on the data read from file before it's stored here, so
+       it will be a single line of data.  */
    char * unprocessed;
+   
+   /** The type of data on this line.  One of the FILE_LINE_xxx constants. */
    int type;
 
+   /** The actual data, processed into some sensible data type. */
    union
    {
+
+      /** An action specification. */
       struct action_spec action[1];
 
+      /** A name=value pair. */
       struct
       {
+
+         /** The name in the name=value pair. */
          char * name;
+
+         /** The value in the name=value pair, as a string. */
          char * svalue;
+
+         /** The value in the name=value pair, as an integer. */
          int ivalue;
+
       } setting;
 
       /* Add more data types here... e.g.
@@ -283,42 +336,65 @@ struct file_line
       */
 
    } data;
+
 };
 
+/** This file_line has not been processed yet. */
 #define FILE_LINE_UNPROCESSED           1
+
+/** This file_line is blank. Can only appear at the end of a file, due to
+    the way the parser works. */
 #define FILE_LINE_BLANK                 2
+
+/** This file_line says {{alias}}. */
 #define FILE_LINE_ALIAS_HEADER          3
+
+/** This file_line defines an alias. */
 #define FILE_LINE_ALIAS_ENTRY           4
+
+/** This file_line defines an {action}. */
 #define FILE_LINE_ACTION                5
+
+/** This file_line specifies a URL pattern. */
 #define FILE_LINE_URL                   6
+
+/** This file_line says {{settings}}. */
 #define FILE_LINE_SETTINGS_HEADER       7
+
+/** This file_line is in a {{settings}} block. */
 #define FILE_LINE_SETTINGS_ENTRY        8
+
+/** This file_line says {{description}}. */
 #define FILE_LINE_DESCRIPTION_HEADER    9
+
+/** This file_line is in a {{description}} block. */
 #define FILE_LINE_DESCRIPTION_ENTRY    10
 
 
+/**
+ * A configuration file, in a format that can be edited and written back to
+ * disk.
+ */
 struct editable_file
 {
-   struct file_line * lines;
-   const char * filename;     /* Full pathname - e.g. "/etc/privoxy/wibble.action" */
-   const char * identifier;   /* Filename stub - e.g. "wibble".  Use for CGI param. */
-                              /* Pre-encoded with url_encode() for ease of use. */
-   const char * version_str;  /* Last modification time, as a string.  For CGI param */
-                              /* Can be used in URL without using url_param(). */
-   unsigned version;          /* Last modification time - prevents chaos with
-                               * the browser's "back" button.  Note that this is a
-                               * time_t cast to an unsigned.  When comparing, always
-                               * cast the time_t to an unsigned, and *NOT* vice-versa.
-                               * This may lose the top few bits, but they're not
-                               * significant anyway.
-                               */
-   int newline;               /* Newline convention - one of the NEWLINE_xxx constants.
-                               * Note that changing this after the file has been
-                               * read in will cause a mess.
-                               */
-   struct file_line * parse_error; /* On parse error, this is the offending line. */
-   const char * parse_error_text;  /* On parse error, this is the problem.
-                                    * (Statically allocated) */
+   struct file_line * lines;  /**< The contents of the file.  A linked list of lines. */
+   const char * filename;     /**< Full pathname - e.g. "/etc/privoxy/wibble.action". */
+   const char * identifier;   /**< Filename stub - e.g. "wibble".  Use for CGI param. */
+                              /**< Pre-encoded with url_encode() for ease of use. */
+   const char * version_str;  /**< Last modification time, as a string.  For CGI param. */
+                              /**< Can be used in URL without using url_param(). */
+   unsigned version;          /**< Last modification time - prevents chaos with
+                                   the browser's "back" button.  Note that this is a
+                                   time_t cast to an unsigned.  When comparing, always
+                                   cast the time_t to an unsigned, and *NOT* vice-versa.
+                                   This may lose the top few bits, but they're not
+                                   significant anyway. */
+   int newline;               /**< Newline convention - one of the NEWLINE_xxx constants.
+                                   Note that changing this after the file has been
+                                   read in will cause a mess. */
+   struct file_line * parse_error; /**< On parse error, this is the offending line. */
+   const char * parse_error_text;  /**< On parse error, this is the problem.
+                                        (Statically allocated) */
 };
 
 /* FIXME: Following non-static functions should be prototyped in .h or made static */
@@ -749,8 +825,7 @@ jb_err cgi_edit_actions_remove_url_form(struct client_state *csp,
  * Description :  Write a complete file to disk.
  *
  * Parameters  :
- *          1  :  filename = File to write to.
- *          2  :  file = Data structure to write.
+ *          1  :  file = File to write.
  *
  * Returns     :  JB_ERR_OK     on success
  *                JB_ERR_FILE   on error writing to file.
@@ -798,9 +873,6 @@ jb_err edit_write_file(struct editable_file * file)
          }
          if (cur_line->unprocessed)
          {
-            /* This should be a single line - sanity check. */
-            assert(NULL == strchr(cur_line->unprocessed, '\r'));
-            assert(NULL == strchr(cur_line->unprocessed, '\n'));
 
             if (NULL != strchr(cur_line->unprocessed, '#'))
             {
@@ -1061,8 +1133,8 @@ static int match_actions_file_header_line(const char * line, const char * name)
  * Parameters  :
  *          1  :  line = String from file.  Must not start with
  *                       whitespace (else infinite loop!)
- *          2  :  name = Destination for name
- *          2  :  name = Destination for value
+ *          2  :  pname = Destination for name
+ *          2  :  pvalue = Destination for value
  *
  * Returns     :  JB_ERR_OK     on success
  *                JB_ERR_MEMORY on out-of-memory
@@ -1440,6 +1512,7 @@ jb_err edit_parse_actions_file(struct editable_file * file)
  *                     at EOF but it will not have been closed.
  *          2  :  pfile = Destination for a linked list of file_lines.
  *                        Will be set to NULL on error.
+ *          3  :  newline = How to handle newlines.
  *
  * Returns     :  JB_ERR_OK     on success
  *                JB_ERR_MEMORY on out-of-memory
@@ -2376,12 +2449,31 @@ jb_err cgi_edit_actions_list(struct client_state *csp,
    {
       /*
        * Generate string with buttons to set actions for "/" to
-       * any predefined set of actions (named standard.*, propably
+       * any predefined set of actions (named standard.*, probably
        * residing in standard.action).
-       * FIXME: Shouldn't include hardwired HTML here, use line template instead!
        */
 
-      buttons = strdup(" ");
+      err = template_load(csp, &section_template, "edit-actions-list-button", 0);
+      if (err)
+      {
+         edit_free_file(file);
+         free_map(exports);
+         if (err == JB_ERR_FILE)
+         {
+            return cgi_error_no_template(csp, rsp, "edit-actions-list-button");
+         }
+         return err;
+      }
+
+      err = template_fill(&section_template, exports);
+      if (err)
+      {
+         edit_free_file(file);
+         free_map(exports);
+         return err;
+      }
+
+      buttons = strdup("");
       for (i = 0; i < MAX_ACTION_FILES; i++)
       {
          if (((fl = csp->actions_list[i]) != NULL) && ((b = fl->f) != NULL))
@@ -2390,27 +2482,49 @@ jb_err cgi_edit_actions_list(struct client_state *csp,
             {
                if (!strncmp(b->url->spec, "standard.", 9) && *(b->url->spec + 9) != '\0')
                {
-                  snprintf(buf, 150, "<p><a name=\"l@s@\" href=\"eas?f=@f@&amp;v=@v@&amp;s=@all-urls-s@&amp;p=%s\">Set"
-                                     " to %s</a></p>", b->url->spec + 9, b->url->spec + 9);
-                  if (!err) err = string_append(&buttons, buf);
+                  if (err || (NULL == (section_exports = new_map())))
+                  {
+                     freez(buttons);
+                     free(section_template);
+                     edit_free_file(file);
+                     free_map(exports);
+                     return JB_ERR_MEMORY;
+                  }
+
+                  err = map(section_exports, "button-name", 1, b->url->spec + 9, 1);
+
+                  if (err || (NULL == (s = strdup(section_template))))
+                  {
+                     free_map(section_exports);
+                     freez(buttons);
+                     free(section_template);
+                     edit_free_file(file);
+                     free_map(exports);
+                     return JB_ERR_MEMORY;
+                  }
+
+                  if (!err) err = template_fill(&s, section_exports);
+                  free_map(section_exports);
+                  if (!err) err = string_join(&buttons, s);
                }
             }
          }
       }
+      freez(section_template);
       if (!err) err = map(exports, "all-urls-buttons", 1, buttons, 0);
 
       /*
        * Conventional actions file, supply extra editing help.
        * (e.g. don't allow them to make it an unconventional one).
        */
-      err = map_conditional(exports, "all-urls-present", 1);
+      if (!err) err = map_conditional(exports, "all-urls-present", 1);
 
       snprintf(buf, 150, "%d", line_number);
       if (!err) err = map(exports, "all-urls-s", 1, buf, 1);
       snprintf(buf, 150, "%d", line_number + 2);
       if (!err) err = map(exports, "all-urls-s-next", 1, buf, 1);
       if (!err) err = map(exports, "all-urls-actions", 1,
-                          actions_to_html(cur_line->data.action), 0);
+                          actions_to_html(csp, cur_line->data.action), 0);
 
        /* Skip the 2 lines */
       cur_line = cur_line->next->next;
@@ -2430,12 +2544,12 @@ jb_err cgi_edit_actions_list(struct client_state *csp,
        * Non-standard actions file - does not begin with
        * the "All URLs" section.
        */
-      err = map_conditional(exports, "all-urls-present", 0);
+      if (!err) err = map_conditional(exports, "all-urls-present", 0);
    }
 
    /* Set up global exports */
 
-   err = map(exports, "f", 1, file->identifier, 1);
+   if (!err) err = map(exports, "f", 1, file->identifier, 1);
    if (!err) err = map(exports, "v", 1, file->version_str, 1);
 
    /* Discourage private additions to default.action */
@@ -2521,7 +2635,7 @@ jb_err cgi_edit_actions_list(struct client_state *csp,
       snprintf(buf, 150, "%d", line_number);
       err = map(section_exports, "s", 1, buf, 1);
       if (!err) err = map(section_exports, "actions", 1,
-                          actions_to_html(cur_line->data.action), 0);
+                          actions_to_html(csp, cur_line->data.action), 0);
 
       if ( (!err)
         && (cur_line->next != NULL)
@@ -2842,6 +2956,8 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp,
          return err;
       }
 
+      err = template_fill(&filter_template, exports);
+
       result = strdup("");
 
       for (;(!err) && (filter_group != NULL); filter_group = filter_group->next)
@@ -2906,6 +3022,9 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp,
             free_map(line_exports);
          }
       }
+
+      freez(filter_template);
+
       if (!err)
       {
          err = map(exports, "filter-params", 1, result, 0);