ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/HostUpdate/HostUpdate.cpp
Revision: 900
Committed: 2007-04-29T02:26:40-07:00 (18 years, 1 month ago) by douglas
File size: 4949 byte(s)
Log Message:
Woo!

File Contents

# Content
1 // Host Update
2 //
3 // Douglas Thrift
4 //
5 // $Id$
6
7 #include "HostUpdate.hpp"
8 #include "Host.hpp"
9
10 #ifndef _WIN32
11
12 #include <resolv.h>
13
14 #else
15
16 #include <windows.h>
17
18 #endif
19
20 int main(int argc, char* argv[])
21 {
22 #ifndef _WIN32
23 ::res_init();
24
25 for (short index(0); index < MAXNS; ++index)
26 if (index + 1 < MAXNS)
27 ::memcpy(&_res.nsaddr_list[index].sin_addr, &_res.nsaddr_list[index + 1].sin_addr, sizeof(in_addr_t));
28 else
29 ::memset(&_res.nsaddr_list[index].sin_addr, 0, sizeof(in_addr_t));
30
31 ::umask(0111);
32 #endif
33
34 HostUpdate update;
35
36 return 0;
37 }
38
39 HostUpdate::HostUpdate() : host(false), name(false), address(false), platform(false), since(false)
40 {
41 {
42 struct ::stat hosts;
43
44 if (::stat("hosts", &hosts) != 0)
45 ::mkdir("hosts");
46 }
47
48 std::string agent = sgetenv("HTTP_USER_AGENT");
49 std::string method = sgetenv("REQUEST_METHOD");
50
51 parse(method);
52 mode();
53
54 if (agent.find("Host Update/") == 0 && method == "POST" && agent.find(" (") != std::string::npos && agent.find(") libwww-perl/") != std::string::npos)
55 update(agent);
56 else if (agent.find("Host Update Sharp/") == 0 && method == "POST" && agent.find(" (") != std::string::npos && agent.find(')') != std::string::npos)
57 update(agent);
58 else
59 display();
60 }
61
62 void HostUpdate::parse(const std::string& method)
63 {
64 std::string query;
65
66 if (method == "POST")
67 std::getline(std::cin, query);
68 else
69 query = sgetenv("QUERY_STRING");
70
71 if (query.empty())
72 return;
73
74 std::istringstream input(query);
75
76 do
77 {
78 std::string name, value;
79
80 std::getline(input, name, '=');
81 std::getline(input, value, '&');
82
83 cgi.insert(std::pair<std::string, std::string>(name, value));
84 }
85 while (input.good());
86 }
87
88 void HostUpdate::mode()
89 {
90 for (std::multimap<std::string, std::string>::iterator itor(cgi.find("mode")); itor != cgi.upper_bound("mode") && itor != cgi.end(); itor++)
91 {
92 std::string mode(itor->second);
93
94 for (std::string::iterator itor(mode.begin()); itor != mode.end(); itor++)
95 {
96 char mode(*itor);
97
98 switch (mode)
99 {
100 case 'h':
101 if (!host)
102 host = true;
103
104 break;
105 case 'n':
106 if (!name)
107 name = true;
108
109 break;
110 case 'a':
111 if (!address)
112 address = true;
113
114 break;
115 case 'p':
116 if (!platform)
117 platform = true;
118
119 break;
120 case 's':
121 if (!since)
122 since = true;
123
124 break;
125 }
126 }
127 }
128
129 if (!host && !name && !address && !platform && !since)
130 host = true, name = true, address = true, platform = true, since = true;
131 }
132
133 void HostUpdate::update(const std::string& agent)
134 {
135 std::cout << "Content-Type: text/plain\n\n";
136
137 std::multimap<std::string, std::string>::iterator itor = cgi.find("host");
138
139 if (itor == cgi.end())
140 return;
141
142 if (itor->second.empty())
143 return;
144
145 std::string host(itor->second), name(sgetenv("REMOTE_HOST")), address(sgetenv("REMOTE_ADDR"));
146
147 std::string::size_type begin(agent.find('(') + 1), end(agent.rfind(')'));
148
149 if (begin >= end)
150 return;
151
152 std::string platform(agent.substr(begin, end - begin));
153
154 Host client(host, name, address, platform), saved(host);
155
156 if (client != ++saved)
157 client--;
158
159 display(client);
160 }
161
162 void HostUpdate::display()
163 {
164 std::cout << "Content-Type: text/plain\n\n";
165
166 {
167 bool request(false);
168
169 for (std::multimap<std::string, std::string>::iterator itor(cgi.find("host")); itor != cgi.upper_bound("host") && itor != cgi.end(); itor++)
170 {
171 if (!itor->second.empty())
172 {
173 Host host(itor->second);
174
175 display(++host);
176
177 if (!request)
178 request = true;
179 }
180 }
181
182 if (request)
183 return;
184 }
185
186 std::set<Host> hosts;
187
188 #ifndef _WIN32
189 DIR* ::dir(opendir("hosts"));
190 struct ::dirent* ent;
191
192 while ((ent = ::readdir(dir)) != NULL)
193 {
194 std::string file(ent->d_name);
195
196 if (file == "." || file == "..")
197 continue;
198
199 Host host(file);
200
201 hosts.insert(++host);
202 }
203
204 ::closedir(dir);
205 #else
206 WIN32_FIND_DATA found;
207 HANDLE find(::FindFirstFile("hosts\\*", &found));
208
209 do
210 {
211 std::string file(found.cFileName);
212
213 if (file == "." || file == "..")
214 continue;
215
216 Host host(file);
217
218 hosts.insert(++host);
219 }
220 while (::FindNextFile(find, &found) != 0);
221
222 ::FindClose(find);
223 #endif
224
225 for (std::set<Host>::iterator itor(hosts.begin()); itor != hosts.end(); itor++)
226 display(*itor);
227 }
228
229 void HostUpdate::display(const Host& host)
230 {
231 if (this->host)
232 std::cout << "host=" << host.getHost() << '\n';
233
234 if (name)
235 std::cout << "name=" << host.getName() << '\n';
236
237 if (address)
238 std::cout << "address=" << host.getAddress() << '\n';
239
240 if (platform)
241 std::cout << "platform=" << host.getPlatform() << '\n';
242
243 std::string name(std::string("hosts") + slash + host.getHost());
244 struct ::stat file;
245
246 if (since && ::stat(name.c_str(), &file) == 0)
247 {
248 char since[20];
249
250 ::strftime(since, 20, "%m/%d/%Y %H:%M:%S", ::gmtime(&file.st_mtime));
251
252 std::cout << "since=" << since << " GMT\n";
253 }
254 else if (since)
255 {
256 char since[20];
257 time_t now(::time(NULL));
258
259 ::strftime(since, 20, "%m/%d/%Y %H:%M:%S", ::gmtime(&now));
260
261 std::cout << "since=" << since << " GMT\n";
262 }
263 }

Properties

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