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