2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
23 $Date: 2010/03/15 12:58:17 $
33 #include "stg/common.h"
38 extern IA_CLIENT_PROT * clnp;
40 #define LISTEN_PORT (5580)
43 //---------------------------------------------------------------------------
52 m_res = WSAStartup(MAKEWORD(2,0), &m_wsaData);
55 for (int i = 0; i < DIR_NUM; i++)
60 memset(&m_ls, 0, sizeof(m_ls));
62 //---------------------------------------------------------------------------
65 m_thread = std::jthread([this](auto token){ Run(std::move(token)); });
67 //---------------------------------------------------------------------------
68 void WEB::PrepareNet()
70 m_listenSocket = socket(PF_INET, SOCK_STREAM, 0);
72 struct sockaddr_in listenAddr;
73 listenAddr.sin_family = AF_INET;
74 listenAddr.sin_port = htons(LISTEN_PORT);
75 listenAddr.sin_addr.s_addr = m_listenWebAddr;
79 if (0 != setsockopt(m_listenSocket, SOL_SOCKET, SO_REUSEADDR, &lng, 4))
81 printf("Setsockopt Fail\n");
82 printf(">>> Error %s\n", strerror(errno));
89 m_res = bind(m_listenSocket, reinterpret_cast<sockaddr*>(&listenAddr), sizeof(listenAddr));
93 printf("Bind failed.\n");
97 m_res = listen(m_listenSocket, 0);
100 printf("Listen failed.\n");
104 //---------------------------------------------------------------------------
105 void WEB::SetRefreshPagePeriod(int p)
108 if (m_refreshPeriod <= 0 || m_refreshPeriod > 24*3600)
111 //---------------------------------------------------------------------------
112 void WEB::SetListenAddr(uint32_t ip)
114 m_listenWebAddr = ip;
116 //---------------------------------------------------------------------------
117 void WEB::Run(std::stop_token token) noexcept
120 sigfillset(&signalSet);
121 pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
124 char recvBuffer[4096];
125 while (!token.stop_requested())
127 struct sockaddr_in outerAddr;
130 socklen_t outerAddrLen = sizeof(outerAddr);
132 int outerAddrLen = sizeof(outerAddr);
135 m_outerSocket = accept(m_listenSocket, reinterpret_cast<sockaddr*>(&outerAddr), &outerAddrLen);
136 if (m_outerSocket == -1)
138 printf(">>> Error %s\n", strerror(errno));
141 recv(m_outerSocket, recvBuffer, sizeof(recvBuffer), 0);
143 if (strncmp(recvBuffer, "GET /sgauth.css", strlen("GET /sgauth.css")) == 0)
146 //printf("(1) recvBuffer=%s\n", recvBuffer);
148 else if (strncmp(recvBuffer, "GET /disconnect", strlen("GET /disconnect")) == 0)
152 //printf("(2) recvBuffer=%s\n", recvBuffer);
154 else if (strncmp(recvBuffer, "GET /connect", strlen("GET /connect")) == 0)
158 //printf("(3) recvBuffer=%s\n", recvBuffer);
160 else if (strncmp(recvBuffer, "GET /exit", strlen("GET /exit")) == 0)
167 struct timespec ts = {1, 0};
168 nanosleep(&ts, NULL);
175 //printf("(4) recvBuffer=%s\n", recvBuffer);
179 closesocket(m_outerSocket);
181 close(m_outerSocket);
185 //---------------------------------------------------------------------------
186 int WEB::Redirect(const char * url)
188 const char * redirect =
190 "Content-Type: text/html\n"
195 "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"0;%s\">\n"
198 "</body></html>\n\n";
201 sprintf(buff, redirect, url);
202 send(m_outerSocket, buff, strlen(buff), 0);
206 //---------------------------------------------------------------------------
211 const char * replyHeader =
213 "Content-Type: text/html\n"
218 "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"%d\">\n"
219 "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=windows-1251\">\n"
220 "<title>sgauth</title>\n"
221 "<link rel=\"Stylesheet\" href=\"sgauth.css\">"
224 "<H3>Stargazer</H3><p>\n";
226 const char * replyFooter = "</body></html>\n\n";
228 char replyHeaderBuffer[2000];
229 sprintf(replyHeaderBuffer, replyHeader, m_refreshPeriod);
231 send(m_outerSocket, replyHeaderBuffer, strlen(replyHeaderBuffer), 0);
235 int st = clnp->GetAuthorized();
237 sprintf(str, "<a href=\"connect\">%s</a><p>\n", gettext("Connect"));
238 m_res = send(m_outerSocket, str, strlen(str), 0);
240 sprintf(str, "<a href=\"disconnect\">%s</a><p>\n", gettext("Disconnect"));
241 m_res = send(m_outerSocket, str, strlen(str), 0);
243 sprintf(str, "<a href=\"/\">%s</a><p>\n", gettext("Refresh"));
244 m_res = send(m_outerSocket, str, strlen(str), 0);
246 sprintf(str, "<a href=\"exit\">%s</a><p>\n", gettext("Exit"));
247 m_res = send(m_outerSocket, str, strlen(str), 0);
249 sprintf(str, "<div id=\"%s\">%s</div><p>\n" , st ? "ConnectionStateOnline":"ConnectionStateOffline", st ? "Online":"Offline");
250 m_res = send(m_outerSocket, str, strlen(str), 0);
252 sprintf(str, "<div id=\"Cash\">%s: %.3f</div><p>\n" , gettext("Cash"), m_ls.cash / 1000.0);
253 m_res = send(m_outerSocket, str, strlen(str), 0);
255 sprintf(str, "<div id=\"Prepaid Traffic\">%s: %s</div><p>\n" ,
256 gettext("PrepaidTraffic"),
257 m_ls.freeMb[0] == 'C' ? m_ls.freeMb + 1 : m_ls.freeMb);
258 m_res = send(m_outerSocket, str, strlen(str), 0);
260 sprintf(str, "<TABLE id=\"TraffTable\">\n");
261 m_res = send(m_outerSocket, str, strlen(str), 0);
262 sprintf(str, " <TR id=\"TraffTableCaptionRow\">\n");
263 m_res = send(m_outerSocket, str, strlen(str), 0);
264 sprintf(str, " <TD id=\"TraffTableCaptionCellC\"> </TD>\n");
265 m_res = send(m_outerSocket, str, strlen(str), 0);
268 for (j = 0; j < DIR_NUM; j++)
270 if (m_dirName[j][0] == 0)
273 KOIToWin(m_dirName[j], &s);// +++++++++ sigsegv ========== TODO too long dir name crashes sgauth
274 sprintf(str, " <TD id=\"TraffTableCaptionCell%d\">%s</TD>\n", rowNum++, s.c_str());
275 send(m_outerSocket, str, strlen(str), 0);
278 sprintf(str," </TR>\n");
279 send(m_outerSocket, str, strlen(str), 0);
281 sprintf(str," <TR id=\"TraffTableUMRow\">\n");
282 send(m_outerSocket, str, strlen(str), 0);
284 sprintf(str," <TD id=\"TraffTableUMCellC\">%s</TD>\n", gettext("Month Upload"));
285 send(m_outerSocket, str, strlen(str), 0);
288 for (j = 0; j < DIR_NUM; j++)
290 if (m_dirName[j][0] == 0)
292 sprintf(str," <TD id=\"TraffTableUMCell%d\">%s</TD>\n", rowNum++, IntToKMG(m_ls.mu[j], ST_F));
293 m_res = send(m_outerSocket, str, strlen(str), 0);
296 sprintf(str," </TR>\n");
297 m_res = send(m_outerSocket, str, strlen(str), 0);
298 sprintf(str," <TR id=\"TraffTableDMRow\">\n");
299 m_res = send(m_outerSocket, str, strlen(str), 0);
300 sprintf(str," <TD id=\"TraffTableDMCellC\">%s</TD>\n", gettext("Month Download"));
301 m_res = send(m_outerSocket, str, strlen(str), 0);
304 for (j = 0; j < DIR_NUM; j++)
306 if (m_dirName[j][0] == 0)
308 sprintf(str," <TD id=\"TraffTableDMCell%d\">%s</TD>\n", rowNum++, IntToKMG(m_ls.md[j], ST_F));
309 m_res = send(m_outerSocket, str, strlen(str), 0);
311 sprintf(str," </TR>\n");
312 m_res = send(m_outerSocket, str, strlen(str), 0);
315 sprintf(str," <TR id=\"TraffTableUSRow\">\n");
316 m_res = send(m_outerSocket, str, strlen(str), 0);
317 sprintf(str," <TD id=\"TraffTableUSCellC\">%s</TD>\n", gettext("Session Upload"));
318 m_res = send(m_outerSocket, str, strlen(str), 0);
321 for (j = 0; j < DIR_NUM; j++)
323 if (m_dirName[j][0] == 0)
325 sprintf(str," <TD id=\"TraffTableUSCell%d\">%s</TD>\n", rowNum++, IntToKMG(m_ls.su[j], ST_F));
326 m_res = send(m_outerSocket, str, strlen(str), 0);
329 sprintf(str," </TR>\n");
330 m_res = send(m_outerSocket, str, strlen(str), 0);
331 sprintf(str," <TR id=\"TraffTableDSRow\">\n");
332 m_res = send(m_outerSocket, str, strlen(str), 0);
333 sprintf(str," <TD id=\"TraffTableDSCellC\">%s</TD>\n", gettext("Session Download"));
334 m_res = send(m_outerSocket, str, strlen(str), 0);
336 for (j = 0; j < DIR_NUM; j++)
338 if (m_dirName[j][0] == 0)
340 sprintf(str," <TD id=\"TraffTableDSCell%d\">%s</TD>\n", j, IntToKMG(m_ls.sd[j], ST_F));
341 m_res = send(m_outerSocket, str, strlen(str), 0);
344 sprintf(str," </TR>\n");
345 m_res = send(m_outerSocket, str, strlen(str), 0);
347 sprintf(str,"</TABLE>\n");
348 m_res = send(m_outerSocket, str, strlen(str), 0);
351 if (!m_messages.empty())
353 sprintf(str," <TABLE id=\"MessagesTable\">\n");
354 m_res = send(m_outerSocket, str, strlen(str), 0);
356 sprintf(str," <TR id=\"MessagesTableRowC\">\n");
357 send(m_outerSocket, str, strlen(str), 0);
358 sprintf(str," <TD>Date</TD>\n");
359 send(m_outerSocket, str, strlen(str), 0);
360 sprintf(str," <TD>Text</TD>\n");
361 send(m_outerSocket, str, strlen(str), 0);
362 sprintf(str," </TR>\n");
363 send(m_outerSocket, str, strlen(str), 0);
365 std::list<STG_MESSAGE>::reverse_iterator it;
366 it = m_messages.rbegin();
367 while (it != m_messages.rend())
369 sprintf(str," <TR id=\"MessagesTableRow%d\">\n", rowNum);
370 send(m_outerSocket, str, strlen(str), 0);
371 sprintf(str," <TD>%s</TD>\n", it->recvTime.c_str());
372 send(m_outerSocket, str, strlen(str), 0);
373 sprintf(str," <TD>%s</TD>\n", it->msg.c_str());
374 send(m_outerSocket, str, strlen(str), 0);
375 sprintf(str," </TR>\n");
376 send(m_outerSocket, str, strlen(str), 0);
381 sprintf(str," </TABLE>\n");
382 m_res = send(m_outerSocket, str, strlen(str), 0);
385 time_t t = time(NULL);
386 sprintf(str,"Îáíîâëåíî: %s</b>" , ctime(&t));
387 m_res = send(m_outerSocket, str, strlen(str), 0);
389 send(m_outerSocket, replyFooter, strlen(replyFooter), 0);
393 //---------------------------------------------------------------------------
396 const char * replyHeader =
398 "Content-Type: text/css\n"
399 "Connection: close\n\n";
401 const char * replyFooter= "\n\n";
403 send(m_outerSocket, replyHeader, strlen(replyHeader), 0);
404 send(m_outerSocket, SGAuth::css, strlen(SGAuth::css), 0);
405 send(m_outerSocket, replyFooter, strlen(replyFooter), 0);
409 //---------------------------------------------------------------------------
410 void WEB::SetDirName(const std::string & dn, int n)
412 web->m_dirName[n] = dn;
414 //---------------------------------------------------------------------------
415 void WEB::AddMessage(const std::string & message, int type)
417 time_t t = time(NULL);
422 m.recvTime = ctime(&t);
424 m_messages.push_back(m);
426 if (m_messages.size() > MAX_MESSAGES)
427 m_messages.pop_front();
430 //---------------------------------------------------------------------------
431 void WEB::UpdateStat(const LOADSTAT & ls)
433 memcpy(&m_ls, &ls, sizeof(LOADSTAT));
435 //---------------------------------------------------------------------------