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

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

Properties

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