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 14 by Douglas Thrift, 2003-11-07T23:04:39-08:00 vs.
Revision 907 by douglas, 2007-04-29T11:27:53-07:00

# Line 7 | Line 7
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   {
19        struct stat* hosts = new struct stat;
20
21        if (stat("hosts", hosts) != 0)
41          {
42 <                mkdir("hosts");
42 >                struct ::stat hosts;
43 >
44 >                if (::stat("hosts", &hosts) != 0)
45 >                        ::mkdir("hosts");
46          }
47  
48 <        delete [] hosts;
48 >        std::string agent = sgetenv("HTTP_USER_AGENT");
49 >        std::string method = sgetenv("REQUEST_METHOD");
50  
51 <        chdir("hosts");
51 >        parse(method);
52 >        mode();
53  
54 <        CgiEnvironment env = cgi.getEnvironment();
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 <        string agent = env.getUserAgent();
63 <        string method = env.getRequestMethod();
62 > void HostUpdate::parse(const std::string& method)
63 > {
64 >        std::string query;
65  
66 <        if (agent.find("Host Update/") == 0 && method == "POST" && agent.find(" (")
67 <                != string::npos && agent.find(") libwww-perl/") != string::npos)
37 <        {
38 <                update(env, agent);
39 <        }
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 <                display(env);
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 < HostUpdate::~HostUpdate()
88 > void HostUpdate::mode()
89   {
90 <        //
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(CgiEnvironment& env, const string& agent)
133 > void HostUpdate::update(const std::string& agent)
134   {
135 <        cout << "Content-Type: text/plain\n\n";
135 >        std::cout << "Content-Type: text/plain\n\n";
136 >
137 >        std::multimap<std::string, std::string>::iterator itor = cgi.find("host");
138  
139 <        vector<FormEntry> entries;
139 >        if (itor == cgi.end())
140 >                return;
141  
142 <        if (!cgi.getElement("host", entries)) return;
143 <        if (entries[0].isEmpty()) return;
142 >        if (itor->second.empty())
143 >                return;
144  
145 <        string host = entries[0].getStrippedValue(), name = env.getRemoteHost(),
61 <                address = env.getRemoteAddr();
145 >        std::string host(itor->second), name(sgetenv("REMOTE_HOST")), address(sgetenv("REMOTE_ADDR"));
146  
147 <        if (name == address) name = "";
147 >        std::string::size_type begin(agent.find('(') + 1), end(agent.rfind(')'));
148  
149 <        string::size_type begin = agent.find('(') + 1, end = agent.find(')',
150 <                begin);
67 <        string platform = agent.substr(begin, end - begin);
149 >        if (begin >= end)
150 >                return;
151  
152 <        cout << "host=" << host << '\n'
70 <                << "name=" << name << '\n'
71 <                << "address=" << address << '\n'
72 <                << "platform=" << platform << '\n';
152 >        std::string platform(agent.substr(begin, end - begin));
153  
154          Host client(host, name, address, platform), saved(host);
155  
156 <        if (client != ++saved) client--;
156 >        if (client != ++saved)
157 >                client--;
158 >
159 >        display(client);
160   }
161  
162 < void HostUpdate::display(CgiEnvironment& env)
162 > void HostUpdate::display()
163   {
164 <        cout << "Content-Type: text/plain\n\n";
164 >        std::cout << "Content-Type: text/plain\n\n";
165 >
166 >        {
167 >                bool request(false);
168  
169 <        set<Host> hosts;
170 <        DIR* dir = opendir(".");
171 <        struct dirent* ent;
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 <        while ((ent = readdir(dir)) != NULL)
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 <                string file = ent->d_name;
194 >                std::string file(ent->d_name);
195  
196 <                cerr << file << '\n';
196 >                if (file.empty() || file[0] == '.')
197 >                        continue;
198  
93                if (file == "." || file == "..") continue;
94                
199                  Host host(file);
200  
201                  hosts.insert(++host);
202          }
99        
100        closedir(dir);
203  
204 <        for (set<Host>::iterator itor = hosts.begin(); itor != hosts.end(); itor++)
204 >        ::closedir(dir);
205 > #else
206 >        WIN32_FIND_DATA found;
207 >        HANDLE find(::FindFirstFile("hosts\\*", &found));
208 >
209 >        do
210          {
211 <                Host host = *itor;
211 >                std::string file(found.cFileName);
212 >
213 >                if (file.empty() || file[0] == '.')
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 <                cout << "host=" << host.getHost() << '\n'
107 <                        << "name=" << host.getName() << '\n'
108 <                        << "address=" << host.getAddress() << '\n'
109 <                        << "platform=" << host.getPlatform() << "\n\n";
261 >                std::cout << "since=" << since << " GMT\n";
262          }
263   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines