11 #include <fcgi_stdio.h>
18 typedef struct parameter_s parameter_t;
20 static parameter_t *parameters = NULL;
21 static size_t parameters_num = 0;
22 static _Bool parameters_init = 0;
24 static int parameter_add (const char *key, const char *value) /* {{{ */
31 ptr = realloc (parameters, sizeof (*parameters) * (parameters_num + 1));
36 ptr = parameters + parameters_num;
43 ptr->key = strdup (key);
48 ptr->value = strdup (value);
49 if (ptr->value == NULL)
57 } /* }}} int parameter_add */
59 static char *parameter_lookup (const char *key) /* {{{ */
63 for (i = 0; i < parameters_num; i++)
65 if ((key == NULL) && (parameters[i].key == NULL))
66 return (parameters[i].value);
67 else if ((key != NULL) && (parameters[i].key != NULL)
68 && (strcmp (key, parameters[i].key) == 0))
69 return (parameters[i].value);
73 } /* }}} char *parameter_lookup */
75 static char *uri_unescape (char *string) /* {{{ */
92 else if ((in[0] == '%')
93 && isxdigit ((int) in[1]) && isxdigit ((int) in[2]))
105 value = strtol (tmpstr, &endptr, /* base = */ 16);
106 if ((endptr == tmpstr) || (errno != 0))
124 } /* while (*in != 0) */
128 } /* }}} char *uri_unescape */
130 static int parse_keyval (char *keyval) /* {{{ */
135 val = strchr (keyval, '=');
148 parameter_add (uri_unescape (key), uri_unescape (val));
151 } /* }}} int parse_keyval */
153 static int parse_query_string (char *query_string) /* {{{ */
158 if (query_string == NULL)
161 dummy = query_string;
162 while ((keyval = strtok (dummy, ";&")) != NULL)
165 parse_keyval (keyval);
169 } /* }}} int parse_query_string */
171 int param_init (void) /* {{{ */
173 const char *query_string;
180 query_string = getenv ("QUERY_STRING");
181 if (query_string == NULL)
184 copy = strdup (query_string);
188 status = parse_query_string (copy);
194 } /* }}} int param_init */
196 void param_finish (void) /* {{{ */
200 if (!parameters_init)
203 for (i = 0; i < parameters_num; i++)
205 free (parameters[i].key);
206 free (parameters[i].value);
213 } /* }}} void param_finish */
215 const char *param (const char *key) /* {{{ */
219 return (parameter_lookup (key));
220 } /* }}} const char *param */
222 int uri_escape (char *dst, const char *src, size_t size) /* {{{ */
236 else if ((src[in] < 32)
239 || (((unsigned char) src[in]) >= 128))
243 if ((size - out) < 4)
246 snprintf (esc, sizeof (esc), "%%%02x", (unsigned int) src[in]);
263 } /* }}} int uri_escape */
265 const char *script_name (void) /* {{{ */
269 ret = getenv ("SCRIPT_NAME");
271 ret = "collection4.fcgi";
274 } /* }}} char *script_name */
276 int time_to_rfc1123 (time_t t, char *buffer, size_t buffer_size) /* {{{ */
281 /* RFC 1123 *requires* the time to be GMT and the "GMT" timezone string.
282 * Apache will ignore the timezone if "localtime_r" and "%z" is used,
283 * resulting in weird behavior. */
284 if (gmtime_r (&t, &tm_tmp) == NULL)
287 status = strftime (buffer, buffer_size, "%a, %d %b %Y %T GMT", &tm_tmp);
292 } /* }}} int time_to_rfc1123 */
294 #define COPY_ENTITY(e) do { \
295 size_t len = strlen (e); \
296 if (dest_size < (len + 1)) \
298 strcpy (dest_ptr, (e)); \
303 char *html_escape_copy (char *dest, const char *src, size_t n) /* {{{ */
312 for (pos = 0; src[pos] != 0; pos++)
315 COPY_ENTITY (""");
316 else if (src[pos] == '<')
317 COPY_ENTITY ("<");
318 else if (src[pos] == '>')
319 COPY_ENTITY (">");
320 else if (src[pos] == '&')
321 COPY_ENTITY ("&");
324 *dest_ptr = src[pos];
335 } /* }}} char *html_escape_copy */
339 char *html_escape_buffer (char *buffer, size_t buffer_size) /* {{{ */
341 char tmp[buffer_size];
343 html_escape_copy (tmp, buffer, sizeof (tmp));
344 memcpy (buffer, tmp, buffer_size);
347 } /* }}} char *html_escape_buffer */
349 char *html_escape (const char *string) /* {{{ */
356 html_escape_copy (buffer, string, sizeof (buffer));
358 return (strdup (buffer));
359 } /* }}} char *html_escape */
361 int html_print_page (const char *title, /* {{{ */
362 const page_callbacks_t *cb, void *user_data)
366 printf ("Content-Type: text/html\n\n");
369 title = "c4: collection4 graph interface";
371 title_html = html_escape (title);
375 " <title>%s</title>\n"
376 " <link rel=\"stylesheet\" type=\"text/css\" href=\"../share/style.css\" />\n"
377 " <script type=\"text/javascript\" src=\"../share/jquery-1.4.2.min.js\">\n"
379 " <script type=\"text/javascript\" src=\"../share/collection.js\">\n"
385 " <table id=\"layout-table\">\n"
386 " <tr id=\"layout-top\">\n"
387 " <td id=\"layout-top-left\">");
388 if (cb->top_left != NULL)
389 (*cb->top_left) (user_data);
391 " <td id=\"layout-top-center\">");
392 if (cb->top_center != NULL)
393 (*cb->top_center) (user_data);
395 printf ("<h1>%s</h1>", title_html);
397 " <td id=\"layout-top-right\">");
398 if (cb->top_right != NULL)
399 (*cb->top_right) (user_data);
402 " <tr id=\"layout-middle\">\n"
403 " <td id=\"layout-middle-left\">");
404 if (cb->middle_left != NULL)
405 (*cb->middle_left) (user_data);
407 " <td id=\"layout-middle-center\">");
408 if (cb->middle_center != NULL)
409 (*cb->middle_center) (user_data);
411 " <td id=\"layout-middle-right\">");
412 if (cb->middle_right != NULL)
413 (*cb->middle_right) (user_data);
416 " <tr id=\"layout-bottom\">\n"
417 " <td id=\"layout-bottom-left\">");
418 if (cb->bottom_left != NULL)
419 (*cb->bottom_left) (user_data);
421 " <td id=\"layout-bottom-center\">");
422 if (cb->bottom_center != NULL)
423 (*cb->bottom_center) (user_data);
425 " <td id=\"layout-bottom-right\">");
426 if (cb->bottom_right != NULL)
427 (*cb->bottom_right) (user_data);
436 } /* }}} int html_print_page */
438 int html_print_search_box (__attribute__((unused)) void *user_data) /* {{{ */
442 term_html = html_escape (param ("search"));
444 printf ("<form action=\"%s\" method=\"get\">\n"
445 " <input type=\"hidden\" name=\"action\" value=\"list_graphs\" />\n"
446 " <input type=\"text\" name=\"search\" value=\"%s\" id=\"search-input\" />\n"
447 " <input type=\"submit\" name=\"button\" value=\"Search\" />\n"
450 (term_html != NULL) ? term_html : "");
455 } /* }}} int html_print_search_box */
457 /* vim: set sw=2 sts=2 et fdm=marker : */