ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/Smersh/Smersh.cpp
Revision: 349
Committed: 2004-12-16T18:15:34-08:00 (20 years, 6 months ago) by douglas
File size: 3959 byte(s)
Log Message:
Horribly broken, including parts of menes.

File Contents

# Content
1 // Smersh
2 //
3 // Douglas Thrift
4 //
5 // $Id$
6
7 #include "Smersh.hpp"
8 #include "Matcher/Matcher.hpp"
9 #include "Person.hpp"
10 #include "Daemon.hpp"
11 #include "Redirector.hpp"
12
13 #include <menes-api/exename.hpp>
14 #include <menes-app/application.hpp>
15
16 struct SmershCommand : public app::Application
17 {
18 virtual int Run(const app::ArgumentList& args)
19 {
20 Smersh::program = api::GetExecutablePath().GetName();
21
22 int port(54321);
23 bool daemon(false), redirector(false);
24 ext::String redirect, log("smersh.log");
25
26 _foreach (app::ArgumentList, arg, args)
27 {
28 Matcher matcher;
29
30 if (*arg == "-daemon")
31 {
32 if (!daemon) daemon = true;
33 }
34 else if (*arg == matcher("^-redirector=(.+)$"))
35 {
36 if (!redirector) redirector = true;
37
38 redirect = matcher[1];
39 }
40 else if (*arg == matcher("^-port=([0-9]+)$"))
41 {
42 port = lexical_cast<int>(matcher[1]);
43 }
44 else if (*arg == matcher("^-log=(.+)$"))
45 {
46 log = matcher[1];
47 }
48 else if (*arg == "-D")
49 {
50 if (!Smersh::debug) Smersh::debug = true;
51 }
52 else
53 {
54 api::Cerr << "Usage: " << Smersh::program << " [-daemon|-redirector=redirect] [-port=port] [-log=log] [-D]\n";
55
56 return 1;
57 }
58 }
59
60 if (daemon)
61 {
62 Daemon daemon(port, log);
63 }
64 else if (redirector)
65 {
66 Redirector redirector(port, log, redirect);
67 }
68 else
69 {
70 Smersh smersh;
71 }
72
73 return 0;
74 }
75 } smersh;
76
77 Smersh::Smersh(std::istream& sin, std::ostream& sout, const Environment& env)
78 {
79 parse(sin, env);
80 smersh(sout, env);
81 }
82
83 ext::String Smersh::program;
84 bool Smersh::debug(false);
85
86 Environment Smersh::env;
87
88 void Smersh::parse(istream& sin, const Environment& env)
89 {
90 std::stringstream query(env.get("QUERY_STRING"));
91
92 if (env.get("REQUEST_METHOD") == "POST")
93 {
94 std::streamsize length(lexical_cast<std::streamsize>(env.get("CONTENT_LENGTH")));
95 char* content(new char[length]);
96
97 sin.read(content, length);
98 query.write(content, length);
99
100 delete [] content;
101 }
102
103 if (query.str() == "") return;
104
105 do
106 {
107 std::string name, value;
108
109 std::getline(query, name, '=');
110 std::getline(query, value, '&');
111
112 cgi.insert(std::pair<std::string, std::string>(name, value));
113 }
114 while (query.good());
115 }
116
117 void Smersh::smersh(std::ostream& sout, const Environment& env)
118 {
119 if (&env == &Smersh::env) sout << "Content-Type: text/html; charset=UTF-8\r\n\r\n";
120
121 ext::RedBlackSet<Person> people;
122
123 typedef std::multimap<std::string, std::string> MultiMap;
124
125 _for (MultiMap::iterator, itor, cgi.lower_bound("sn"), cgi.upper_bound("sn"))
126 {
127 std::string sn(itor->second);
128
129 for (std::string::size_type index(0); index < sn.length(); ++index)
130 {
131 while (!isalnum(sn[index]) && index < sn.length())
132 {
133 if (sn[index] == '%' && index + 2 < sn.length())
134 {
135 std::istringstream code(sn.substr(index + 1, 2));
136 unsigned short character;
137
138 code.setf(std::ios_base::hex, std::ios_base::basefield);
139
140 code >> character;
141
142 sn.replace(index, 3, 1, character);
143
144 if (isalnum(sn[index])) break;
145 }
146
147 sn.erase(index, 1);
148 }
149 }
150
151 if (debug) cerr << "sn = " << sn << '\n';
152
153 Person person(sn);
154
155 people.Insert(person);
156
157 if (person.isMultiple())
158 {
159 _foreach (ext::Vector<Person>, single, person.getMultiple()) people.Insert(*single);
160
161 person.clearMultiple();
162 }
163 }
164
165 if (people.IsEmpty()) people.Insert(Person());
166
167 sout << "<html><head><title>Hello, " << std::flush;
168
169 output(sout, people);
170
171 sout << "!</title></head><body><p style=\"font-variant: small-caps\"><strong><font face=\"Comic Sans MS\" size=\"4\">Hello, " << std::flush;
172
173 output(sout, people);
174
175 sout << "!</font></strong></p></body></html>\r\n";
176 }
177
178 void Smersh::output(std::ostream& sout, const ext::RedBlackSet<Person>& people)
179 {
180 _foreach (ext::RedBlackSet<Person>, person, people)
181 {
182 sout << *person;
183
184 if (person + 2 == people.End())
185 {
186 sout << (people.GetSize() > 2 ? "," : "") << " and/or ";
187 }
188 else if (person + 1 != people.End())
189 {
190 sout << ", ";
191 }
192
193 sout << std::flush;
194 }
195 }

Properties

Name Value
svn:eol-style native
svn:keywords Id