X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/4271ab433cd55bbd2612292bcf39e4dc3d7274f1..0907aa4037b12b6b88ee24495d4577a064d4f8db:/projects/sgauth/web.cpp diff --git a/projects/sgauth/web.cpp b/projects/sgauth/web.cpp new file mode 100644 index 00000000..a162acc4 --- /dev/null +++ b/projects/sgauth/web.cpp @@ -0,0 +1,461 @@ +/* + * 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 + */ + + /* + $Revision: 1.7 $ + $Date: 2010/03/15 12:58:17 $ + */ + +#include + +#include +#include +#include +#include + +#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" + "\n" + "\n" + "\n" + "\n" + "\n" + "\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" + "\n" + "\n" + "\n" + "\n" + "sgauth\n" + "" + "\n" + "\n" + "

Stargazer

\n"; + +const char * replyFooter = "\n\n"; + +char replyHeaderBuffer[2000]; +sprintf(replyHeaderBuffer, replyHeader, refreshPeriod); + +send(outerSocket, replyHeaderBuffer, strlen(replyHeaderBuffer), 0); + +char str[512]; + +int st = clnp->GetAuthorized(); + +sprintf(str, "%s

\n", gettext("Connect")); +res = send(outerSocket, str, strlen(str), 0); + +sprintf(str, "%s

\n", gettext("Disconnect")); +res = send(outerSocket, str, strlen(str), 0); + +sprintf(str, "%s

\n", gettext("Refresh")); +res = send(outerSocket, str, strlen(str), 0); + +sprintf(str, "%s

\n", gettext("Exit")); +res = send(outerSocket, str, strlen(str), 0); + +sprintf(str, "

%s

\n" , st ? "ConnectionStateOnline":"ConnectionStateOffline", st ? "Online":"Offline"); +res = send(outerSocket, str, strlen(str), 0); + +sprintf(str, "

%s: %.3f

\n" , gettext("Cash"), ls.cash / 1000.0); +res = send(outerSocket, str, strlen(str), 0); + +sprintf(str, "

%s: %s

\n" , + gettext("PrepaidTraffic"), + ls.freeMb[0] == 'C' ? ls.freeMb + 1 : ls.freeMb); +res = send(outerSocket, str, strlen(str), 0); + +sprintf(str, "\n"); +res = send(outerSocket, str, strlen(str), 0); +sprintf(str, " \n"); +res = send(outerSocket, str, strlen(str), 0); +sprintf(str, " \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, " \n", rowNum++, s.c_str()); + send(outerSocket, str, strlen(str), 0); + } + +sprintf(str," \n"); +send(outerSocket, str, strlen(str), 0); + +sprintf(str," \n"); +send(outerSocket, str, strlen(str), 0); + +sprintf(str," \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," \n", rowNum++, IntToKMG(ls.mu[j], ST_F)); + res = send(outerSocket, str, strlen(str), 0); + } + +sprintf(str," \n"); +res = send(outerSocket, str, strlen(str), 0); +sprintf(str," \n"); +res = send(outerSocket, str, strlen(str), 0); +sprintf(str," \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," \n", rowNum++, IntToKMG(ls.md[j], ST_F)); + res = send(outerSocket, str, strlen(str), 0); + } +sprintf(str," \n"); +res = send(outerSocket, str, strlen(str), 0); + + +sprintf(str," \n"); +res = send(outerSocket, str, strlen(str), 0); +sprintf(str," \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," \n", rowNum++, IntToKMG(ls.su[j], ST_F)); + res = send(outerSocket, str, strlen(str), 0); + } + +sprintf(str," \n"); +res = send(outerSocket, str, strlen(str), 0); +sprintf(str," \n"); +res = send(outerSocket, str, strlen(str), 0); +sprintf(str," \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," \n", j, IntToKMG(ls.sd[j], ST_F)); + res = send(outerSocket, str, strlen(str), 0); + } + +sprintf(str," \n"); +res = send(outerSocket, str, strlen(str), 0); + +sprintf(str,"
 %s
%s%s
%s%s
%s%s
%s%s
\n"); +res = send(outerSocket, str, strlen(str), 0); + +rowNum = 0; +if (!messages.empty()) + { + sprintf(str," \n"); + res = send(outerSocket, str, strlen(str), 0); + + sprintf(str," \n"); + send(outerSocket, str, strlen(str), 0); + sprintf(str," \n"); + send(outerSocket, str, strlen(str), 0); + sprintf(str," \n"); + send(outerSocket, str, strlen(str), 0); + sprintf(str," \n"); + send(outerSocket, str, strlen(str), 0); + + std::list::reverse_iterator it; + it = messages.rbegin(); + while (it != messages.rend()) + { + sprintf(str," \n", rowNum); + send(outerSocket, str, strlen(str), 0); + sprintf(str," \n", it->recvTime.c_str()); + send(outerSocket, str, strlen(str), 0); + sprintf(str," \n", it->msg.c_str()); + send(outerSocket, str, strlen(str), 0); + sprintf(str," \n"); + send(outerSocket, str, strlen(str), 0); + ++it; + ++rowNum; + } + + sprintf(str,"
DateText
%s%s
\n"); + res = send(outerSocket, str, strlen(str), 0); + } + +time_t t = time(NULL); +sprintf(str,"Îáíîâëåíî: %s" , 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, SGAuth::css, strlen(SGAuth::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)); +} +//--------------------------------------------------------------------------- +