ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/HostUpdate/HostUpdate.cpp
Revision: 192
Committed: 2004-08-22T21:23:29-07:00 (20 years, 10 months ago) by Douglas Thrift
File size: 4738 byte(s)
Log Message:
Meep!

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

Properties

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