[ci] Fix netbsd job to upgrade existing packages
[xapian.git] / xapian-applications / omega / cgiparam.cc
blob71f31ef7ab9afe34c79dc884c6e80b63da3a2b1a
1 /** @file
2 * @brief functions to deal with CGI parameters
3 */
4 /* Copyright 1999,2000,2001 BrightStation PLC
5 * Copyright 2001 James Aylett
6 * Copyright 2001 Ananova Ltd
7 * Copyright 2002,2003,2009,2011,2015,2017 Olly Betts
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
22 * USA
25 #include <config.h>
27 #include "cgiparam.h"
29 #include "urldecode.h"
30 #include "urlencode.h"
32 #include <cstdio>
33 #include <climits>
34 #include <cstdlib>
35 #include <cstring>
36 #include <map>
37 #include <string>
39 using namespace std;
41 multimap<string, string> cgi_params;
43 static void
44 add_param(string name, string val)
46 size_t i = name.length();
47 if (i > 2 && name[i - 2] == '.') {
48 // An image button called B gives B.x and B.y parameters with the
49 // coordinates of the click. We throw away the ".y" one and trim
50 // ".x" from the other.
51 if (name[i - 1] == 'y') return;
52 if (name[i - 1] == 'x') {
53 name.resize(i - 2);
54 // For an image button, the value of the CGI parameter is the
55 // coordinate of the click within the image - this is meaningless
56 // to us, so instead we turn "[ 2 ].x=NNN" into "[ 2 ]=2 ]", then
57 // below that gets turned into "[=2 ]". The trailing non-numeric
58 // characters are ignored by atoi().
59 i = name.find_first_of(" \t");
60 if (i != string::npos)
61 val.assign(name, i + 1, string::npos);
62 else {
63 i = name.find_first_not_of("0123456789");
64 if (i == string::npos) {
65 // For image buttons with entirely numeric names, make the
66 // value the name, and the name "#" - e.g. "2.x=NNN" becomes
67 // "#=2".
68 val = name;
69 name = '#';
70 } else {
71 // Otherwise we just copy the name into the value, so
72 // ">.x=NNN" becomes ">=>".
73 val = name;
78 // Truncate at first space or tab - convert '[ page two ]=2'
79 // into '[=2'
80 i = name.find_first_of(" \t");
81 if (i != string::npos) name.resize(i);
82 cgi_params.insert(multimap<string, string>::value_type(name, val));
85 void
86 CGIParameterHandler::operator()(const string& var, const string& val) const
88 add_param(var, val);
91 void
92 decode_argv(char **argv)
94 cgi_params.clear();
95 while (*argv) {
96 char *p = strchr(*argv, '=');
97 if (p) {
98 add_param(string(*argv, p), p + 1);
99 } else {
100 add_param(*argv, "");
102 ++argv;
106 void
107 decode_test()
109 cgi_params.clear();
110 while (!feof(stdin)) {
111 string name, val;
112 bool had_equals = false;
113 while (1) {
114 int ch = getchar();
115 if (ch == EOF || ch == '\n') {
116 if (name.empty()) return; // end on blank line
117 add_param(name, val);
118 break;
120 if (had_equals) {
121 val += char(ch);
122 } else if (ch == '=') {
123 had_equals = true;
124 } else {
125 name += char(ch);
131 void
132 decode_post()
134 char *content_length;
135 size_t cl = INT_MAX;
137 content_length = getenv("CONTENT_LENGTH");
138 /* Netscape Fasttrack server for NT doesn't give CONTENT_LENGTH */
139 if (content_length) cl = atoi(content_length);
141 cgi_params.clear();
142 url_decode(CGIParameterHandler(), StdinItor(cl), StdinItor());
145 void
146 decode_get()
148 cgi_params.clear();
149 const char *q_str = getenv("QUERY_STRING");
150 // If QUERY_STRING isn't set, that's pretty broken, but don't segfault.
151 if (q_str)
152 url_decode(CGIParameterHandler(), CStringItor(q_str), CStringItor());