15 typedef struct parameter_s parameter_t;
17 static parameter_t *parameters = NULL;
18 static size_t parameters_num = 0;
19 static _Bool parameters_init = 0;
21 static int parameter_add (const char *key, const char *value) /* {{{ */
28 ptr = realloc (parameters, sizeof (*parameters) * (parameters_num + 1));
33 ptr = parameters + parameters_num;
40 ptr->key = strdup (key);
45 ptr->value = strdup (value);
46 if (ptr->value == NULL)
54 } /* }}} int parameter_add */
56 static char *parameter_lookup (const char *key) /* {{{ */
60 for (i = 0; i < parameters_num; i++)
62 if ((key == NULL) && (parameters[i].key == NULL))
63 return (parameters[i].value);
64 else if ((key != NULL) && (parameters[i].key != NULL)
65 && (strcmp (key, parameters[i].key) == 0))
66 return (parameters[i].value);
70 } /* }}} char *parameter_lookup */
72 static char *uri_unescape (char *string) /* {{{ */
89 else if ((in[0] == '%')
90 && isxdigit ((int) in[1]) && isxdigit ((int) in[2]))
102 value = strtol (tmpstr, &endptr, /* base = */ 16);
103 if ((endptr == tmpstr) || (errno != 0))
121 } /* while (*in != 0) */
125 } /* }}} char *uri_unescape */
127 static int parse_keyval (char *keyval) /* {{{ */
132 val = strchr (keyval, '=');
145 parameter_add (uri_unescape (key), uri_unescape (val));
148 } /* }}} int parse_keyval */
150 static int parse_query_string (char *query_string) /* {{{ */
155 if (query_string == NULL)
158 dummy = query_string;
159 while ((keyval = strtok (dummy, ";&")) != NULL)
162 parse_keyval (keyval);
166 } /* }}} int parse_query_string */
168 int param_init (void) /* {{{ */
170 const char *query_string;
177 query_string = getenv ("QUERY_STRING");
178 if (query_string == NULL)
181 copy = strdup (query_string);
185 status = parse_query_string (copy);
191 } /* }}} int param_init */
193 void param_finish (void) /* {{{ */
197 if (!parameters_init)
200 for (i = 0; i < parameters_num; i++)
202 free (parameters[i].key);
203 free (parameters[i].value);
210 } /* }}} void param_finish */
212 const char *param (const char *key) /* {{{ */
216 return (parameter_lookup (key));
217 } /* }}} const char *param */
219 int uri_escape (char *dst, const char *src, size_t size) /* {{{ */
233 else if ((src[in] < 32)
236 || (((unsigned char) src[in]) >= 128))
240 if ((size - out) < 4)
243 snprintf (esc, sizeof (esc), "%%%02x", (unsigned int) src[in]);
260 } /* }}} int uri_escape */
262 const char *script_name (void) /* {{{ */
266 ret = getenv ("SCRIPT_NAME");
268 ret = "collection4.fcgi";
271 } /* }}} char *script_name */
273 int time_to_rfc1123 (time_t t, char *buffer, size_t buffer_size) /* {{{ */
278 /* RFC 1123 *requires* the time to be GMT and the "GMT" timezone string.
279 * Apache will ignore the timezone if "localtime_r" and "%z" is used,
280 * resulting in weird behavior. */
281 if (gmtime_r (&t, &tm_tmp) == NULL)
284 status = strftime (buffer, buffer_size, "%a, %d %b %Y %T GMT", &tm_tmp);
289 } /* }}} int time_to_rfc1123 */
291 /* vim: set sw=2 sts=2 et fdm=marker : */