ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/HostUpdate/HostUpdate.cpp
(Generate patch)

Comparing HostUpdate/HostUpdate.cpp (file contents):
Revision 3 by Douglas Thrift, 2003-11-05T18:37:16-08:00 vs.
Revision 900 by douglas, 2007-04-29T02:26:40-07:00

# Line 5 | Line 5
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()
39 > HostUpdate::HostUpdate() : host(false), name(false), address(false), platform(false), since(false)
40   {
41 <        CgiEnvironment env = cgi.getEnvironment();
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 <        cout << "Location: " << (env.usingHTTPS() ? "https" : "http") << "://"
81 <                << env.getServerName() << ":" << env.getServerPort() << "/\n\n";
80 >                std::getline(input, name, '=');
81 >                std::getline(input, value, '&');
82  
83 <        form_iterator itor = cgi["host"];
84 <        FormEntry host = *itor;
83 >                cgi.insert(std::pair<std::string, std::string>(name, value));
84 >        }
85 >        while (input.good());
86   }
87  
88 < HostUpdate::~HostUpdate()
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   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines