-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
- */
-
- /*
- $Revision: 1.7 $
- $Date: 2010/03/15 12:58:17 $
- */
-
-#include <libintl.h>
-
-#include <csignal>
-#include <cstdio>
-#include <cstring>
-#include <ctime>
-
-#include "stg/common.h"
-#include "stg/ia.h"
-#include "web.h"
-
-extern WEB * web;
-extern IA_CLIENT_PROT * clnp;
-
-#define LISTEN_PORT (5580)
-
-#include "css.h"
-
-//---------------------------------------------------------------------------
-#ifndef WIN32
-void * RunWeb(void *)
-{
-sigset_t signalSet;
-sigfillset(&signalSet);
-pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
-
-#else
-unsigned long WINAPI RunWeb(void *)
-{
-#endif
-while (1)
- web->Run();
-return NULL;
-}
-//---------------------------------------------------------------------------
-WEB::WEB()
- : res(0),
- listenSocket(0),
- outerSocket(0),
- refreshPeriod(0),
- listenWebAddr(0)
-{
-#ifdef WIN32
-res = WSAStartup(MAKEWORD(2,0), &wsaData);
-#endif
-
-for (int i = 0; i < DIR_NUM; i++)
- dirName[i] = "-";
-
-refreshPeriod = 5;
-
-memset(&ls, 0, sizeof(ls));
-}
-//---------------------------------------------------------------------------
-void WEB::Start()
-{
-#ifdef WIN32
-unsigned long pt;
-CreateThread(
- NULL, // pointer to thread security attributes
- 16384, // initial thread stack size, in bytes
- RunWeb, // pointer to thread function
- NULL, // argument for new thread
- 0, // CREATE_SUSPENDED, // creation flags
- &pt // pointer to returned thread identifier
- );
-#else
-pthread_create(&thread, NULL, RunWeb, NULL);
-#endif
-}
-//---------------------------------------------------------------------------
-void WEB::PrepareNet()
-{
-listenSocket = socket(PF_INET, SOCK_STREAM, 0);
-
-struct sockaddr_in listenAddr;
-listenAddr.sin_family = AF_INET;
-listenAddr.sin_port = htons(LISTEN_PORT);
-listenAddr.sin_addr.s_addr = listenWebAddr;
-
-#ifndef WIN32
-int lng = 1;
-if (0 != setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, &lng, 4))
- {
- printf("Setsockopt Fail\n");
- printf(">>> Error %s\n", strerror(errno));
- }
-#else
-//??? TODO
-#endif
-
-
-res = bind(listenSocket, (struct sockaddr*)&listenAddr, sizeof(listenAddr));
-
-if (res == -1)
- {
- printf("Bind failed.\n");
- exit(0);
- }
-
-res = listen(listenSocket, 0);
-if (res == -1)
- {
- printf("Listen failed.\n");
- exit(0);
- }
-}
-//---------------------------------------------------------------------------
-void WEB::SetRefreshPagePeriod(int p)
-{
-refreshPeriod = p;
-if (refreshPeriod <= 0 || refreshPeriod > 24*3600)
- refreshPeriod = 5;
-}
-//---------------------------------------------------------------------------
-void WEB::SetListenAddr(uint32_t ip)
-{
-listenWebAddr = ip;
-}
-//---------------------------------------------------------------------------
-void WEB::Run()
-{
-PrepareNet();
-char recvBuffer[4096];
-while (1)
- {
- struct sockaddr_in outerAddr;
-
- #ifndef WIN32
- socklen_t outerAddrLen = sizeof(outerAddr);
- #else
- int outerAddrLen = sizeof(outerAddr);
- #endif
-
- outerSocket = accept(listenSocket, (struct sockaddr*)&outerAddr, &outerAddrLen);
- if (outerSocket == -1)
- {
- printf(">>> Error %s\n", strerror(errno));
- continue;
- }
- recv(outerSocket, recvBuffer, sizeof(recvBuffer), 0);
-
- if (strncmp(recvBuffer, "GET /sgauth.css", strlen("GET /sgauth.css")) == 0)
- {
- SendCSS();
- //printf("(1) recvBuffer=%s\n", recvBuffer);
- }
- else if (strncmp(recvBuffer, "GET /disconnect", strlen("GET /disconnect")) == 0)
- {
- clnp->Disconnect();
- Redirect("/");
- //printf("(2) recvBuffer=%s\n", recvBuffer);
- }
- else if (strncmp(recvBuffer, "GET /connect", strlen("GET /connect")) == 0)
- {
- clnp->Connect();
- Redirect("/");
- //printf("(3) recvBuffer=%s\n", recvBuffer);
- }
- else if (strncmp(recvBuffer, "GET /exit", strlen("GET /exit")) == 0)
- {
- Redirect("/");
- clnp->Disconnect();
- #ifdef WIN32
- Sleep(1000);
- #else
- struct timespec ts = {1, 0};
- nanosleep(&ts, NULL);
- #endif
- exit(0);
- }
- else
- {
- SendReply();
- //printf("(4) recvBuffer=%s\n", recvBuffer);
- }
-
- #ifdef WIN32
- closesocket(outerSocket);
- #else
- close(outerSocket);
- #endif
- }
-}
-//---------------------------------------------------------------------------
-int WEB::Redirect(const char * url)
-{
-const char * redirect =
- "HTTP/1.0 200 OK\n"
- "Content-Type: text/html\n"
- "Connection: close"
- "\n\n"
- "<html>\n"
- "<head>\n"
- "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"0;%s\">\n"
- "</head>\n"
- "<body>\n"
- "</body></html>\n\n";
-
-char buff[2000];
-sprintf(buff, redirect, url);
-send(outerSocket, buff, strlen(buff), 0);
-
-return 0;
-}
-//---------------------------------------------------------------------------
-int WEB::SendReply()
-{
-int j, rowNum;
-
-const char * replyHeader =
- "HTTP/1.0 200 OK\n"
- "Content-Type: text/html\n"
- "Connection: close"
- "\n\n"
- "<html>\n"
- "<head>\n"
- "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"%d\">\n"
- "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=windows-1251\">\n"
- "<title>sgauth</title>\n"
- "<link rel=\"Stylesheet\" href=\"sgauth.css\">"
- "</head>\n"
- "<body>\n"
- "<H3>Stargazer</H3><p>\n";
-
-const char * replyFooter = "</body></html>\n\n";
-
-char replyHeaderBuffer[2000];
-sprintf(replyHeaderBuffer, replyHeader, refreshPeriod);
-
-send(outerSocket, replyHeaderBuffer, strlen(replyHeaderBuffer), 0);
-
-char str[512];
-
-int st = clnp->GetAuthorized();
-
-sprintf(str, "<a href=\"connect\">%s</a><p>\n", gettext("Connect"));
-res = send(outerSocket, str, strlen(str), 0);
-
-sprintf(str, "<a href=\"disconnect\">%s</a><p>\n", gettext("Disconnect"));
-res = send(outerSocket, str, strlen(str), 0);
-
-sprintf(str, "<a href=\"/\">%s</a><p>\n", gettext("Refresh"));
-res = send(outerSocket, str, strlen(str), 0);
-
-sprintf(str, "<a href=\"exit\">%s</a><p>\n", gettext("Exit"));
-res = send(outerSocket, str, strlen(str), 0);
-
-sprintf(str, "<div id=\"%s\">%s</div><p>\n" , st ? "ConnectionStateOnline":"ConnectionStateOffline", st ? "Online":"Offline");
-res = send(outerSocket, str, strlen(str), 0);
-
-sprintf(str, "<div id=\"Cash\">%s: %.3f</div><p>\n" , gettext("Cash"), ls.cash / 1000.0);
-res = send(outerSocket, str, strlen(str), 0);
-
-sprintf(str, "<div id=\"Prepaid Traffic\">%s: %s</div><p>\n" ,
- gettext("PrepaidTraffic"),
- ls.freeMb[0] == 'C' ? ls.freeMb + 1 : ls.freeMb);
-res = send(outerSocket, str, strlen(str), 0);
-
-sprintf(str, "<TABLE id=\"TraffTable\">\n");
-res = send(outerSocket, str, strlen(str), 0);
-sprintf(str, " <TR id=\"TraffTableCaptionRow\">\n");
-res = send(outerSocket, str, strlen(str), 0);
-sprintf(str, " <TD id=\"TraffTableCaptionCellC\"> </TD>\n");
-res = send(outerSocket, str, strlen(str), 0);
-
-rowNum = 0;
-for (j = 0; j < DIR_NUM; j++)
- {
- if (dirName[j][0] == 0)
- continue;
- std::string s;
- KOIToWin(dirName[j], &s);// +++++++++ sigsegv ========== TODO too long dir name crashes sgauth
- sprintf(str, " <TD id=\"TraffTableCaptionCell%d\">%s</TD>\n", rowNum++, s.c_str());
- send(outerSocket, str, strlen(str), 0);
- }
-
-sprintf(str," </TR>\n");
-send(outerSocket, str, strlen(str), 0);
-
-sprintf(str," <TR id=\"TraffTableUMRow\">\n");
-send(outerSocket, str, strlen(str), 0);
-
-sprintf(str," <TD id=\"TraffTableUMCellC\">%s</TD>\n", gettext("Month Upload"));
-send(outerSocket, str, strlen(str), 0);
-
-rowNum = 0;
-for (j = 0; j < DIR_NUM; j++)
- {
- if (dirName[j][0] == 0)
- continue;
- sprintf(str," <TD id=\"TraffTableUMCell%d\">%s</TD>\n", rowNum++, IntToKMG(ls.mu[j], ST_F));
- res = send(outerSocket, str, strlen(str), 0);
- }
-
-sprintf(str," </TR>\n");
-res = send(outerSocket, str, strlen(str), 0);
-sprintf(str," <TR id=\"TraffTableDMRow\">\n");
-res = send(outerSocket, str, strlen(str), 0);
-sprintf(str," <TD id=\"TraffTableDMCellC\">%s</TD>\n", gettext("Month Download"));
-res = send(outerSocket, str, strlen(str), 0);
-
-rowNum = 0;
-for (j = 0; j < DIR_NUM; j++)
- {
- if (dirName[j][0] == 0)
- continue;
- sprintf(str," <TD id=\"TraffTableDMCell%d\">%s</TD>\n", rowNum++, IntToKMG(ls.md[j], ST_F));
- res = send(outerSocket, str, strlen(str), 0);
- }
-sprintf(str," </TR>\n");
-res = send(outerSocket, str, strlen(str), 0);
-
-
-sprintf(str," <TR id=\"TraffTableUSRow\">\n");
-res = send(outerSocket, str, strlen(str), 0);
-sprintf(str," <TD id=\"TraffTableUSCellC\">%s</TD>\n", gettext("Session Upload"));
-res = send(outerSocket, str, strlen(str), 0);
-
-rowNum = 0;
-for (j = 0; j < DIR_NUM; j++)
- {
- if (dirName[j][0] == 0)
- continue;
- sprintf(str," <TD id=\"TraffTableUSCell%d\">%s</TD>\n", rowNum++, IntToKMG(ls.su[j], ST_F));
- res = send(outerSocket, str, strlen(str), 0);
- }
-
-sprintf(str," </TR>\n");
-res = send(outerSocket, str, strlen(str), 0);
-sprintf(str," <TR id=\"TraffTableDSRow\">\n");
-res = send(outerSocket, str, strlen(str), 0);
-sprintf(str," <TD id=\"TraffTableDSCellC\">%s</TD>\n", gettext("Session Download"));
-res = send(outerSocket, str, strlen(str), 0);
-
-for (j = 0; j < DIR_NUM; j++)
- {
- if (dirName[j][0] == 0)
- continue;
- sprintf(str," <TD id=\"TraffTableDSCell%d\">%s</TD>\n", j, IntToKMG(ls.sd[j], ST_F));
- res = send(outerSocket, str, strlen(str), 0);
- }
-
-sprintf(str," </TR>\n");
-res = send(outerSocket, str, strlen(str), 0);
-
-sprintf(str,"</TABLE>\n");
-res = send(outerSocket, str, strlen(str), 0);
-
-rowNum = 0;
-if (!messages.empty())
- {
- sprintf(str," <TABLE id=\"MessagesTable\">\n");
- res = send(outerSocket, str, strlen(str), 0);
-
- sprintf(str," <TR id=\"MessagesTableRowC\">\n");
- send(outerSocket, str, strlen(str), 0);
- sprintf(str," <TD>Date</TD>\n");
- send(outerSocket, str, strlen(str), 0);
- sprintf(str," <TD>Text</TD>\n");
- send(outerSocket, str, strlen(str), 0);
- sprintf(str," </TR>\n");
- send(outerSocket, str, strlen(str), 0);
-
- std::list<STG_MESSAGE>::reverse_iterator it;
- it = messages.rbegin();
- while (it != messages.rend())
- {
- sprintf(str," <TR id=\"MessagesTableRow%d\">\n", rowNum);
- send(outerSocket, str, strlen(str), 0);
- sprintf(str," <TD>%s</TD>\n", it->recvTime.c_str());
- send(outerSocket, str, strlen(str), 0);
- sprintf(str," <TD>%s</TD>\n", it->msg.c_str());
- send(outerSocket, str, strlen(str), 0);
- sprintf(str," </TR>\n");
- send(outerSocket, str, strlen(str), 0);
- ++it;
- ++rowNum;
- }
-
- sprintf(str," </TABLE>\n");
- res = send(outerSocket, str, strlen(str), 0);
- }
-
-time_t t = time(NULL);
-sprintf(str,"Îáíîâëåíî: %s</b>" , ctime(&t));
-res = send(outerSocket, str, strlen(str), 0);
-
-send(outerSocket, replyFooter, strlen(replyFooter), 0);
-
-return 0;
-}
-//---------------------------------------------------------------------------
-int WEB::SendCSS()
-{
-const char * replyHeader =
- "HTTP/1.0 200 OK\n"
- "Content-Type: text/css\n"
- "Connection: close\n\n";
-
-const char * replyFooter= "\n\n";
-
-send(outerSocket, replyHeader, strlen(replyHeader), 0);
-send(outerSocket, css, strlen(css), 0);
-send(outerSocket, replyFooter, strlen(replyFooter), 0);
-
-return 0;
-}
-//---------------------------------------------------------------------------
-void WEB::SetDirName(const std::string & dn, int n)
-{
-web->dirName[n] = dn;
-}
-//---------------------------------------------------------------------------
-void WEB::AddMessage(const std::string & message, int type)
-{
-time_t t = time(NULL);
-STG_MESSAGE m;
-
-m.msg = message;
-m.type = type;
-m.recvTime = ctime(&t);
-
-messages.push_back(m);
-
-if (messages.size() > MAX_MESSAGES)
- messages.pop_front();
-
-}
-//---------------------------------------------------------------------------
-void WEB::UpdateStat(const LOADSTAT & ls)
-{
-memcpy((void*)&(WEB::ls), &ls, sizeof(LOADSTAT));
-}
-//---------------------------------------------------------------------------
-