Merge branch 'master' of verplant.org:/var/lib/git/collection4
[collection4.git] / src / utils_cgi.c
index ac9daca..97dfc7c 100644 (file)
@@ -7,6 +7,9 @@
 
 #include "utils_cgi.h"
 
+#include <fcgiapp.h>
+#include <fcgi_stdio.h>
+
 struct parameter_s
 {
   char *key;
@@ -290,48 +293,165 @@ int time_to_rfc1123 (time_t t, char *buffer, size_t buffer_size) /* {{{ */
 
 #define COPY_ENTITY(e) do {    \
   size_t len = strlen (e);     \
-  if (buffer_size < (len + 1)) \
+  if (dest_size < (len + 1)) \
     break;                     \
-  strcpy (buffer_ptr, (e));    \
-  buffer_ptr += len;           \
-  buffer_size -= len;          \
+  strcpy (dest_ptr, (e));    \
+  dest_ptr += len;           \
+  dest_size -= len;          \
 } while (0)
 
-char *html_escape (const char *string) /* {{{ */
+char *html_escape_copy (char *dest, const char *src, size_t n) /* {{{ */
 {
-  char buffer[4096];
-  char *buffer_ptr;
-  size_t buffer_size;
+  char *dest_ptr;
+  size_t dest_size;
   size_t pos;
 
-  buffer[0] = 0;
-  buffer_ptr = &buffer[0];
-  buffer_size = sizeof (buffer);
-  for (pos = 0; string[pos] != 0; pos++)
+  dest[0] = 0;
+  dest_ptr = dest;
+  dest_size = n;
+  for (pos = 0; src[pos] != 0; pos++)
   {
-    if (string[pos] == '"')
+    if (src[pos] == '"')
       COPY_ENTITY ("&quot;");
-    else if (string[pos] == '<')
+    else if (src[pos] == '<')
       COPY_ENTITY ("&lt;");
-    else if (string[pos] == '>')
+    else if (src[pos] == '>')
       COPY_ENTITY ("&gt;");
-    else if (string[pos] == '&')
+    else if (src[pos] == '&')
       COPY_ENTITY ("&amp;");
     else
     {
-      *buffer_ptr = string[pos];
-      buffer_ptr++;
-      buffer_size--;
-      *buffer_ptr = 0;
+      *dest_ptr = src[pos];
+      dest_ptr++;
+      dest_size--;
+      *dest_ptr = 0;
     }
 
-    if (buffer_size <= 1)
+    if (dest_size <= 1)
       break;
   }
 
+  return (dest);
+} /* }}} char *html_escape_copy */
+
+#undef COPY_ENTITY
+
+char *html_escape_buffer (char *buffer, size_t buffer_size) /* {{{ */
+{
+  char tmp[buffer_size];
+
+  html_escape_copy (tmp, buffer, sizeof (tmp));
+  memcpy (buffer, tmp, buffer_size);
+
+  return (buffer);
+} /* }}} char *html_escape_buffer */
+
+char *html_escape (const char *string) /* {{{ */
+{
+  char buffer[4096];
+
+  if (string == NULL)
+    return (NULL);
+
+  html_escape_copy (buffer, string, sizeof (buffer));
+
   return (strdup (buffer));
 } /* }}} char *html_escape */
 
-#undef COPY_ENTITY
+int html_print_page (const char *title, /* {{{ */
+    const page_callbacks_t *cb, void *user_data)
+{
+  char *title_html;
+
+  printf ("Content-Type: text/html\n\n");
+
+  if (title == NULL)
+    title = "c4: collection4 graph interface";
+
+  title_html = html_escape (title);
+
+  printf ("<html>\n"
+      "  <head>\n"
+      "    <title>%s</title>\n"
+      "    <link rel=\"stylesheet\" type=\"text/css\" href=\"../share/style.css\" />\n"
+      "    <script type=\"text/javascript\" src=\"../share/jquery-1.4.2.min.js\">\n"
+      "    </script>\n"
+      "    <script type=\"text/javascript\" src=\"../share/collection.js\">\n"
+      "    </script>\n"
+      "  </head>\n",
+      title_html);
+
+  printf ("  <body>\n"
+      "    <table id=\"layout-table\">\n"
+      "      <tr id=\"layout-top\">\n"
+      "        <td id=\"layout-top-left\">");
+  if (cb->top_left != NULL)
+    (*cb->top_left) (user_data);
+  printf ("</td>\n"
+      "        <td id=\"layout-top-center\">");
+  if (cb->top_center != NULL)
+    (*cb->top_center) (user_data);
+  else
+    printf ("<h1>%s</h1>", title_html);
+  printf ("</td>\n"
+      "        <td id=\"layout-top-right\">");
+  if (cb->top_right != NULL)
+    (*cb->top_right) (user_data);
+  printf ("</td>\n"
+      "      </tr>\n"
+      "      <tr id=\"layout-middle\">\n"
+      "        <td id=\"layout-middle-left\">");
+  if (cb->middle_left != NULL)
+    (*cb->middle_left) (user_data);
+  printf ("</td>\n"
+      "        <td id=\"layout-middle-center\">");
+  if (cb->middle_center != NULL)
+    (*cb->middle_center) (user_data);
+  printf ("</td>\n"
+      "        <td id=\"layout-middle-right\">");
+  if (cb->middle_right != NULL)
+    (*cb->middle_right) (user_data);
+  printf ("</td>\n"
+      "      </tr>\n"
+      "      <tr id=\"layout-bottom\">\n"
+      "        <td id=\"layout-bottom-left\">");
+  if (cb->bottom_left != NULL)
+    (*cb->bottom_left) (user_data);
+  printf ("</td>\n"
+      "        <td id=\"layout-bottom-center\">");
+  if (cb->bottom_center != NULL)
+    (*cb->bottom_center) (user_data);
+  printf ("</td>\n"
+      "        <td id=\"layout-bottom-right\">");
+  if (cb->bottom_right != NULL)
+    (*cb->bottom_right) (user_data);
+  printf ("</td>\n"
+      "      </tr>\n"
+      "    </table>\n"
+      "  </body>\n"
+      "</html>\n");
+
+  free (title_html);
+  return (0);
+} /* }}} int html_print_page */
+
+int html_print_search_box (__attribute__((unused)) void *user_data) /* {{{ */
+{
+  char *term_html;
+
+  term_html = html_escape (param ("q"));
+
+  printf ("<form action=\"%s\" method=\"get\" id=\"search-form\">\n"
+      "  <input type=\"hidden\" name=\"action\" value=\"list_graphs\" />\n"
+      "  <input type=\"text\" name=\"q\" value=\"%s\" id=\"search-input\" />\n"
+      "  <input type=\"submit\" name=\"button\" value=\"Search\" />\n"
+      "</form>\n",
+      script_name (),
+      (term_html != NULL) ? term_html : "");
+
+  free (term_html);
+
+  return (0);
+} /* }}} int html_print_search_box */
 
 /* vim: set sw=2 sts=2 et fdm=marker : */