summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: c3e2812)
raw | patch | inline | side by side (parent: c3e2812)
author | Florian Forster <ff@octo.it> | |
Wed, 23 Jun 2010 15:54:48 +0000 (17:54 +0200) | ||
committer | Florian Forster <octo@leeloo.lan.home.verplant.org> | |
Wed, 23 Jun 2010 15:54:48 +0000 (17:54 +0200) |
src/utils_cgi.c | patch | blob | history | |
src/utils_cgi.h | patch | blob | history |
diff --git a/src/utils_cgi.c b/src/utils_cgi.c
index 97dfc7c60b9a9bdd6e8b588d7645fcd9a8ea63c4..b96e15aeb53340c14918184cbfe1bdfd26d0ea5d 100644 (file)
--- a/src/utils_cgi.c
+++ b/src/utils_cgi.c
#include <ctype.h>
#include <errno.h>
#include <time.h>
+#include <assert.h>
#include "utils_cgi.h"
+#include "common.h"
#include <fcgiapp.h>
#include <fcgi_stdio.h>
};
typedef struct parameter_s parameter_t;
-static parameter_t *parameters = NULL;
-static size_t parameters_num = 0;
-static _Bool parameters_init = 0;
-
-static int parameter_add (const char *key, const char *value) /* {{{ */
+struct param_list_s
{
- parameter_t *ptr;
-
- if (value == NULL)
- return (EINVAL);
-
- ptr = realloc (parameters, sizeof (*parameters) * (parameters_num + 1));
- if (ptr == NULL)
- return (ENOMEM);
- parameters = ptr;
-
- ptr = parameters + parameters_num;
- if (key == NULL)
- {
- ptr->key = NULL;
- }
- else
- {
- ptr->key = strdup (key);
- if (ptr->key == NULL)
- return (ENOMEM);
- }
-
- ptr->value = strdup (value);
- if (ptr->value == NULL)
- {
- free (ptr->key);
- return (ENOMEM);
- }
-
- parameters_num++;
- return (0);
-} /* }}} int parameter_add */
-
-static char *parameter_lookup (const char *key) /* {{{ */
-{
- size_t i;
-
- for (i = 0; i < parameters_num; i++)
- {
- if ((key == NULL) && (parameters[i].key == NULL))
- return (parameters[i].value);
- else if ((key != NULL) && (parameters[i].key != NULL)
- && (strcmp (key, parameters[i].key) == 0))
- return (parameters[i].value);
- }
+ parameter_t *parameters;
+ size_t parameters_num;
+};
- return (NULL);
-} /* }}} char *parameter_lookup */
+static param_list_t *pl_global = NULL;
-static char *uri_unescape (char *string) /* {{{ */
+static char *uri_unescape_copy (char *dest, const char *src, size_t n) /* {{{ */
{
- char *in;
- char *out;
+ const char *src_ptr;
+ char *dest_ptr;
- if (string == NULL)
+ if ((dest == NULL) || (src == NULL) || (n < 1))
return (NULL);
- in = string;
- out = string;
+ src_ptr = src;
+ dest_ptr = dest;
+
+ *dest_ptr = 0;
- while (*in != 0)
+ while (*src_ptr != 0)
{
- if (*in == '+')
+ if (n < 2)
+ break;
+
+ if (*src_ptr == '+')
{
- *out = ' ';
+ *dest_ptr = ' ';
}
- else if ((in[0] == '%')
- && isxdigit ((int) in[1]) && isxdigit ((int) in[2]))
+ else if ((src_ptr[0] == '%')
+ && isxdigit ((int) src_ptr[1]) && isxdigit ((int) src_ptr[2]))
{
char tmpstr[3];
char *endptr;
long value;
- tmpstr[0] = in[1];
- tmpstr[1] = in[2];
+ tmpstr[0] = src_ptr[1];
+ tmpstr[1] = src_ptr[2];
tmpstr[2] = 0;
errno = 0;
value = strtol (tmpstr, &endptr, /* base = */ 16);
if ((endptr == tmpstr) || (errno != 0))
{
- *out = '?';
+ *dest_ptr = '?';
}
else
{
- *out = (char) value;
+ *dest_ptr = (char) value;
}
- in += 2;
+ src_ptr += 2;
}
else
{
- *out = *in;
+ *dest_ptr = *src_ptr;
}
- in++;
- out++;
- } /* while (*in != 0) */
+ src_ptr++;
+ dest_ptr++;
+ *dest_ptr = 0;
+ } /* while (*src_ptr != 0) */
+
+ assert (*dest_ptr == 0);
+ return (dest);
+} /* }}} char *uri_unescape */
+
+static char *uri_unescape (const char *string) /* {{{ */
+{
+ char buffer[4096];
- *out = 0;
- return (string);
+ if (string == NULL)
+ return (NULL);
+
+ uri_unescape_copy (buffer, string, sizeof (buffer));
+
+ return (strdup (buffer));
} /* }}} char *uri_unescape */
-static int parse_keyval (char *keyval) /* {{{ */
+static int param_parse_keyval (param_list_t *pl, char *keyval) /* {{{ */
{
+ char *key_raw;
+ char *value_raw;
char *key;
- char *val;
+ char *value;
- val = strchr (keyval, '=');
- if (val == NULL)
- {
- key = NULL;
- val = keyval;
- }
- else
+ key_raw = keyval;
+ value_raw = strchr (key_raw, '=');
+ if (value_raw == NULL)
+ return (EINVAL);
+ *value_raw = 0;
+ value_raw++;
+
+ key = uri_unescape (key_raw);
+ if (key == NULL)
+ return (ENOMEM);
+
+ value = uri_unescape (value_raw);
+ if (value == NULL)
{
- key = keyval;
- *val = 0;
- val++;
+ free (key);
+ return (ENOMEM);
}
+
+ param_set (pl, key, value);
- parameter_add (uri_unescape (key), uri_unescape (val));
+ free (key);
+ free (value);
return (0);
-} /* }}} int parse_keyval */
+} /* }}} int param_parse_keyval */
-static int parse_query_string (char *query_string) /* {{{ */
+static int parse_query_string (param_list_t *pl, /* {{{ */
+ char *query_string)
{
char *dummy;
char *keyval;
- if (query_string == NULL)
+ if ((pl == NULL) || (query_string == NULL))
return (EINVAL);
dummy = query_string;
while ((keyval = strtok (dummy, ";&")) != NULL)
{
dummy = NULL;
- parse_keyval (keyval);
+ param_parse_keyval (pl, keyval);
}
return (0);
int param_init (void) /* {{{ */
{
- const char *query_string;
- char *copy;
- int status;
-
- if (parameters_init)
+ if (pl_global != NULL)
return (0);
- query_string = getenv ("QUERY_STRING");
+ pl_global = param_create (/* query string = */ NULL);
+ if (pl_global == NULL)
+ return (ENOMEM);
+
+ return (0);
+} /* }}} int param_init */
+
+void param_finish (void) /* {{{ */
+{
+ param_destroy (pl_global);
+ pl_global = NULL;
+} /* }}} void param_finish */
+
+const char *param (const char *key) /* {{{ */
+{
+ param_init ();
+
+ return (param_get (pl_global, key));
+} /* }}} const char *param */
+
+param_list_t *param_create (const char *query_string) /* {{{ */
+{
+ char *tmp;
+ param_list_t *pl;
+
if (query_string == NULL)
- return (ENOENT);
+ query_string = getenv ("QUERY_STRING");
- copy = strdup (query_string);
- if (copy == NULL)
- return (ENOMEM);
+ if (query_string == NULL)
+ return (NULL);
+
+ tmp = strdup (query_string);
+ if (tmp == NULL)
+ return (NULL);
+
+ pl = malloc (sizeof (*pl));
+ if (pl == NULL)
+ {
+ free (tmp);
+ return (NULL);
+ }
+ memset (pl, 0, sizeof (*pl));
- status = parse_query_string (copy);
- free (copy);
+ parse_query_string (pl, tmp);
- parameters_init = 1;
+ free (tmp);
+ return (pl);
+} /* }}} param_list_t *param_create */
- return (status);
-} /* }}} int param_init */
+ param_list_t *param_clone (__attribute__((unused)) param_list_t *pl) /* {{{ */
+{
+ /* FIXME: To be implemented. */
+ assert (23 == 42);
+ return (NULL);
+} /* }}} param_list_t *param_clone */
-void param_finish (void) /* {{{ */
+void param_destroy (param_list_t *pl) /* {{{ */
{
size_t i;
- if (!parameters_init)
+ if (pl == NULL)
return;
- for (i = 0; i < parameters_num; i++)
+ for (i = 0; i < pl->parameters_num; i++)
{
- free (parameters[i].key);
- free (parameters[i].value);
+ free (pl->parameters[i].key);
+ free (pl->parameters[i].value);
}
- free (parameters);
+ free (pl->parameters);
+ free (pl);
+} /* }}} void param_destroy */
- parameters = NULL;
- parameters_num = 0;
- parameters_init = 0;
-} /* }}} void param_finish */
+const char *param_get (param_list_t *pl, const char *name) /* {{{ */
+{
+ size_t i;
-const char *param (const char *key) /* {{{ */
+ if ((pl == NULL) || (name == NULL))
+ return (NULL);
+
+ for (i = 0; i < pl->parameters_num; i++)
+ {
+ if ((name == NULL) && (pl->parameters[i].key == NULL))
+ return (pl->parameters[i].value);
+ else if ((name != NULL) && (pl->parameters[i].key != NULL)
+ && (strcmp (name, pl->parameters[i].key) == 0))
+ return (pl->parameters[i].value);
+ }
+
+ return (NULL);
+} /* }}} char *param_get */
+
+static int param_add (param_list_t *pl, /* {{{ */
+ const char *key, const char *value)
{
- param_init ();
+ parameter_t *tmp;
- return (parameter_lookup (key));
-} /* }}} const char *param */
+ tmp = realloc (pl->parameters,
+ sizeof (*pl->parameters) * (pl->parameters_num + 1));
+ if (tmp == NULL)
+ return (ENOMEM);
+ pl->parameters = tmp;
+ tmp = pl->parameters + pl->parameters_num;
+
+ memset (tmp, 0, sizeof (*tmp));
+ tmp->key = strdup (key);
+ if (tmp->key == NULL)
+ return (ENOMEM);
+
+ tmp->value = strdup (value);
+ if (tmp->value == NULL)
+ {
+ free (tmp->key);
+ return (ENOMEM);
+ }
+
+ pl->parameters_num++;
+
+ return (0);
+} /* }}} int param_add */
+
+static int param_delete (param_list_t *pl, /* {{{ */
+ const char *name)
+{
+ size_t i;
+
+ if ((pl == NULL) || (name == NULL))
+ return (EINVAL);
+
+ for (i = 0; i < pl->parameters_num; i++)
+ if (strcasecmp (pl->parameters[i].key, name) == 0)
+ break;
+
+ if (i >= pl->parameters_num)
+ return (ENOENT);
+
+ if (i < (pl->parameters_num - 1))
+ {
+ parameter_t p;
+
+ p = pl->parameters[i];
+ pl->parameters[i] = pl->parameters[pl->parameters_num - 1];
+ pl->parameters[pl->parameters_num - 1] = p;
+ }
+
+ pl->parameters_num--;
+ free (pl->parameters[pl->parameters_num].key);
+ free (pl->parameters[pl->parameters_num].value);
+
+ return (0);
+} /* }}} int param_delete */
+
+int param_set (param_list_t *pl, const char *name, /* {{{ */
+ const char *value)
+{
+ parameter_t *p;
+ char *value_copy;
+ size_t i;
+
+ if ((pl == NULL) || (name == NULL))
+ return (EINVAL);
+
+ if (value == NULL)
+ return (param_delete (pl, name));
+
+ p = NULL;
+ for (i = 0; i < pl->parameters_num; i++)
+ {
+ if (strcasecmp (pl->parameters[i].key, name) == 0)
+ {
+ p = pl->parameters + i;
+ break;
+ }
+ }
+
+ if (p == NULL)
+ return (param_add (pl, name, value));
+
+ value_copy = strdup (value);
+ if (value_copy == NULL)
+ return (ENOMEM);
+
+ free (p->value);
+ p->value = value_copy;
+
+ return (0);
+} /* }}} int param_set */
+
+const char *param_as_string (param_list_t *pl) /* {{{ */
+{
+ char buffer[4096];
+ char key[2048];
+ char value[2048];
+ size_t i;
+
+ if (pl == NULL)
+ return (NULL);
+
+ buffer[0] = 0;
+ for (i = 0; i < pl->parameters_num; i++)
+ {
+ uri_escape_copy (key, pl->parameters[i].key, sizeof (key));
+ uri_escape_copy (value, pl->parameters[i].value, sizeof (value));
+
+ if (i != 0)
+ strlcat (buffer, ";", sizeof (buffer));
+ strlcat (buffer, key, sizeof (buffer));
+ strlcat (buffer, "=", sizeof (buffer));
+ strlcat (buffer, value, sizeof (buffer));
+ }
+
+ return (strdup (buffer));
+} /* }}} char *param_as_string */
-int uri_escape (char *dst, const char *src, size_t size) /* {{{ */
+int param_print_hidden (param_list_t *pl) /* {{{ */
+{
+ char key[2048];
+ char value[2048];
+ size_t i;
+
+ if (pl == NULL)
+ return (EINVAL);
+
+ for (i = 0; i < pl->parameters_num; i++)
+ {
+ html_escape_copy (key, pl->parameters[i].key, sizeof (key));
+ html_escape_copy (value, pl->parameters[i].value, sizeof (value));
+
+ printf (" <input type=\"hidden\" name=\"%s\" value=\"%s\" />\n",
+ key, value);
+ }
+
+ return (0);
+} /* }}} int param_print_hidden */
+
+char *uri_escape_copy (char *dest, const char *src, size_t n) /* {{{ */
{
size_t in;
size_t out;
{
if (src[in] == 0)
{
- dst[out] = 0;
- return (0);
+ dest[out] = 0;
+ return (dest);
}
- else if ((src[in] < 32)
+ else if ((((unsigned char) src[in]) < 32)
|| (src[in] == '&')
|| (src[in] == ';')
+ || (src[in] == '?')
+ || (src[in] == '/')
|| (((unsigned char) src[in]) >= 128))
{
char esc[4];
- if ((size - out) < 4)
+ if ((n - out) < 4)
break;
snprintf (esc, sizeof (esc), "%%%02x", (unsigned int) src[in]);
- dst[out] = esc[0];
- dst[out+1] = esc[1];
- dst[out+2] = esc[2];
+ dest[out] = esc[0];
+ dest[out+1] = esc[1];
+ dest[out+2] = esc[2];
out += 3;
in++;
}
else
{
- dst[out] = src[in];
+ dest[out] = src[in];
out++;
in++;
}
} /* while (42) */
- return (0);
-} /* }}} int uri_escape */
+ return (dest);
+} /* }}} char *uri_escape_copy */
+
+char *uri_escape (const char *string) /* {{{ */
+{
+ char buffer[4096];
+
+ if (string == NULL)
+ return (NULL);
+
+ uri_escape_copy (buffer, string, sizeof (buffer));
+
+ return (strdup (buffer));
+} /* }}} char *uri_escape */
const char *script_name (void) /* {{{ */
{
diff --git a/src/utils_cgi.h b/src/utils_cgi.h
index e8e847ec430e39f4e0748c42c0c6235ed2aed4e9..973d3f36c5822c230d3f6c0e8c7ab930dca75f25 100644 (file)
--- a/src/utils_cgi.h
+++ b/src/utils_cgi.h
};
typedef struct page_callbacks_s page_callbacks_t;
+struct param_list_s;
+typedef struct param_list_s param_list_t;
+
#define PAGE_CALLBACKS_INIT \
{ NULL, NULL, NULL, \
NULL, NULL, NULL, \
const char *param (const char *key);
-int uri_escape (char *dst, const char *src, size_t size);
+/* Create a new parameter list from "query_string". If "query_string" is NULL,
+ * the "QUERY_STRING" will be used. */
+param_list_t *param_create (const char *query_string);
+param_list_t *param_clone (param_list_t *pl);
+void param_destroy (param_list_t *pl);
+const char *param_get (param_list_t *pl, const char *name);
+int param_set (param_list_t *pl,
+ const char *name, const char *value);
+const char *param_as_string (param_list_t *pl);
+int param_print_hidden (param_list_t *pl);
+
+char *uri_escape (const char *string);
+char *uri_escape_buffer (char *buffer, size_t buffer_size);
+char *uri_escape_copy (char *dest, const char *src, size_t n);
const char *script_name (void);