ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/HostUpdate/HostUpdate.cpp
Revision: 91
Committed: 2004-03-01T19:41:20-08:00 (21 years, 3 months ago) by Douglas Thrift
File size: 4431 byte(s)
Log Message:
Ooh, now it works with HostUpdateSharp!

File Contents

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

Properties

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