Source for additional projects
-jsoncpp -lua -tolua++ -WebServer -zlib -iniFile git-svn-id: http://mc-server.googlecode.com/svn/trunk@4 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
386d58b586
commit
aafef187ef
278
WebServer/Socket.cpp
Normal file
278
WebServer/Socket.cpp
Normal file
@ -0,0 +1,278 @@
|
||||
/*
|
||||
Socket.cpp
|
||||
|
||||
Copyright (C) 2002-2004 René Nyffenegger
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||
*/
|
||||
|
||||
/*
|
||||
Note on point 2:
|
||||
THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1
|
||||
*/
|
||||
|
||||
#include "../source/cMCLogger.h"
|
||||
|
||||
#include "Socket.h"
|
||||
#include <iostream>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <cstring>
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#define MSG_NOSIGNAL (0)
|
||||
#endif
|
||||
|
||||
#ifdef __MAC_NA
|
||||
#define MSG_NOSIGNAL (0)
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
int Socket::nofSockets_= 0;
|
||||
|
||||
void Socket::Start() {
|
||||
#ifdef _WIN32
|
||||
if (!nofSockets_) {
|
||||
WSADATA info;
|
||||
if (WSAStartup(MAKEWORD(2,0), &info)) {
|
||||
throw "Could not start WSA";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
++nofSockets_;
|
||||
}
|
||||
|
||||
void Socket::End() {
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
Socket::Socket() : s_(0) {
|
||||
Start();
|
||||
// UDP: use SOCK_DGRAM instead of SOCK_STREAM
|
||||
s_ = socket(AF_INET,SOCK_STREAM,0);
|
||||
|
||||
#ifdef _WIN32
|
||||
if(s_ ==INVALID_SOCKET)
|
||||
#else
|
||||
if(s_ < 0)
|
||||
#endif
|
||||
{
|
||||
throw "INVALID_SOCKET";
|
||||
}
|
||||
|
||||
refCounter_ = new int(1);
|
||||
}
|
||||
|
||||
Socket::Socket(SOCKET s) : s_(s) {
|
||||
Start();
|
||||
refCounter_ = new int(1);
|
||||
};
|
||||
|
||||
Socket::~Socket() {
|
||||
if (! --(*refCounter_)) {
|
||||
Close();
|
||||
delete refCounter_;
|
||||
}
|
||||
|
||||
--nofSockets_;
|
||||
if (!nofSockets_) End();
|
||||
}
|
||||
|
||||
Socket::Socket(const Socket& o) {
|
||||
refCounter_=o.refCounter_;
|
||||
(*refCounter_)++;
|
||||
s_ =o.s_;
|
||||
|
||||
nofSockets_++;
|
||||
}
|
||||
|
||||
Socket& Socket::operator=(Socket& o) {
|
||||
(*o.refCounter_)++;
|
||||
|
||||
refCounter_=o.refCounter_;
|
||||
s_ =o.s_;
|
||||
|
||||
nofSockets_++;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Socket::Close() {
|
||||
if( s_ )
|
||||
{
|
||||
closesocket(s_);
|
||||
s_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::string Socket::ReceiveLine() {
|
||||
std::string ret;
|
||||
while (1) {
|
||||
char r;
|
||||
|
||||
if (recv(s_, &r, 1, 0) <= 0 )
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
ret += r;
|
||||
if (r == '\n') return ret;
|
||||
}
|
||||
}
|
||||
|
||||
void Socket::SendLine(std::string s) {
|
||||
s += '\n';
|
||||
if( send(s_,s.c_str(),s.length(),MSG_NOSIGNAL) <= 0 )
|
||||
{
|
||||
//printf("SendLine Socket error!! \n" );
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
void Socket::SendBytes(const std::string& s) {
|
||||
if( send(s_,s.c_str(),s.length(), MSG_NOSIGNAL) <= 0 )
|
||||
{
|
||||
//printf("SendBytes Socket error!! \n" );
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
SocketServer::SocketServer(int port, int connections, TypeSocket type) {
|
||||
sockaddr_in sa;
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
|
||||
sa.sin_family = PF_INET;
|
||||
sa.sin_port = htons(port);
|
||||
s_ = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
#ifdef _WIN32
|
||||
if(s_ ==INVALID_SOCKET)
|
||||
#else
|
||||
if(s_ < 0)
|
||||
#endif
|
||||
{
|
||||
LOG("WebServer: INVALID_SOCKET");
|
||||
}
|
||||
|
||||
if(type==NonBlockingSocket) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
char yes = 1;
|
||||
#else
|
||||
int yes = 1;
|
||||
#endif
|
||||
if (setsockopt(s_,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
|
||||
LOG("WebServer: setsockopt == -1");
|
||||
return;
|
||||
}
|
||||
|
||||
/* bind the socket to the internet address */
|
||||
if (bind(s_, (sockaddr *)&sa, sizeof(sockaddr_in)) == SOCKET_ERROR) {
|
||||
closesocket(s_);
|
||||
LOG("WebServer: INVALID_SOCKET");
|
||||
}
|
||||
|
||||
listen(s_, connections);
|
||||
}
|
||||
|
||||
Socket* SocketServer::Accept()
|
||||
{
|
||||
|
||||
SOCKET new_sock = accept(s_, 0, 0);
|
||||
#ifdef _WIN32
|
||||
if(new_sock==INVALID_SOCKET || s_ == 0)
|
||||
#else
|
||||
if(new_sock < 0 || s_ == 0)
|
||||
#endif
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int rc = WSAGetLastError();
|
||||
if(rc==WSAEWOULDBLOCK) {
|
||||
return 0; // non-blocking call, no request pending
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
//throw "Invalid Socket";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Socket* r = new Socket(new_sock);
|
||||
return r;
|
||||
}
|
||||
|
||||
SocketClient::SocketClient(const std::string& host, int port) : Socket() {
|
||||
std::string error;
|
||||
|
||||
hostent *he;
|
||||
if ((he = gethostbyname(host.c_str())) == 0) {
|
||||
#ifdef _WIN32
|
||||
error = strerror(errno);
|
||||
#endif
|
||||
throw error;
|
||||
}
|
||||
|
||||
sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
addr.sin_addr = *((in_addr *)he->h_addr);
|
||||
memset(&(addr.sin_zero), 0, 8);
|
||||
|
||||
if (::connect(s_, (sockaddr *) &addr, sizeof(sockaddr))) {
|
||||
#ifdef _WIN32
|
||||
error = strerror(WSAGetLastError());
|
||||
#endif
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
struct timeval;
|
||||
#endif
|
||||
|
||||
SocketSelect::SocketSelect(Socket const * const s1, Socket const * const s2, TypeSocket type) {
|
||||
FD_ZERO(&fds_);
|
||||
FD_SET(const_cast<Socket*>(s1)->s_,&fds_);
|
||||
if(s2) {
|
||||
FD_SET(const_cast<Socket*>(s2)->s_,&fds_);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
TIMEVAL *ptval = 0;
|
||||
#else
|
||||
timeval *ptval = 0;
|
||||
#endif
|
||||
|
||||
if (select (0, &fds_, (fd_set*) 0, (fd_set*) 0, ptval) == SOCKET_ERROR)
|
||||
throw "Error in select";
|
||||
}
|
||||
|
||||
bool SocketSelect::Readable(Socket const* const s) {
|
||||
if (FD_ISSET(s->s_,&fds_)) return true;
|
||||
return false;
|
||||
}
|
106
WebServer/Socket.h
Normal file
106
WebServer/Socket.h
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
Socket.h
|
||||
|
||||
Copyright (C) 2002-2004 René Nyffenegger
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||
*/
|
||||
|
||||
/*
|
||||
Note on point 2:
|
||||
THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1
|
||||
*/
|
||||
|
||||
#ifndef SOCKET_H
|
||||
#define SOCKET_H
|
||||
|
||||
#include "../source/MCSocket.h"
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
enum TypeSocket {BlockingSocket, NonBlockingSocket};
|
||||
|
||||
class Socket {
|
||||
public:
|
||||
|
||||
virtual ~Socket();
|
||||
Socket(const Socket&);
|
||||
Socket& operator=(Socket&);
|
||||
|
||||
std::string ReceiveLine();
|
||||
std::string ReceiveBytes();
|
||||
|
||||
void Close();
|
||||
|
||||
// The parameter of SendLine is not a const reference
|
||||
// because SendLine modifes the std::string passed.
|
||||
void SendLine (std::string);
|
||||
|
||||
// The parameter of SendBytes is a const reference
|
||||
// because SendBytes does not modify the std::string passed
|
||||
// (in contrast to SendLine).
|
||||
void SendBytes(const std::string&);
|
||||
|
||||
protected:
|
||||
friend class SocketServer;
|
||||
friend class SocketSelect;
|
||||
|
||||
Socket(SOCKET s);
|
||||
Socket();
|
||||
|
||||
|
||||
SOCKET s_;
|
||||
|
||||
int* refCounter_;
|
||||
|
||||
private:
|
||||
static void Start();
|
||||
static void End();
|
||||
static int nofSockets_;
|
||||
};
|
||||
|
||||
class SocketClient : public Socket {
|
||||
public:
|
||||
SocketClient(const std::string& host, int port);
|
||||
};
|
||||
|
||||
class SocketServer : public Socket {
|
||||
public:
|
||||
SocketServer(int port, int connections, TypeSocket type=BlockingSocket);
|
||||
|
||||
Socket* Accept();
|
||||
};
|
||||
|
||||
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/wsapiref_2tiq.asp
|
||||
class SocketSelect {
|
||||
public:
|
||||
SocketSelect(Socket const * const s1, Socket const * const s2=NULL, TypeSocket type=BlockingSocket);
|
||||
|
||||
bool Readable(Socket const * const s);
|
||||
|
||||
private:
|
||||
fd_set fds_;
|
||||
};
|
||||
|
||||
#endif
|
61
WebServer/StdHelpers.cpp
Normal file
61
WebServer/StdHelpers.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
stdHelpers.cpp
|
||||
|
||||
Copyright (C) 2002-2004 René Nyffenegger
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||
*/
|
||||
|
||||
/*
|
||||
Note on point 2:
|
||||
THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1
|
||||
*/
|
||||
|
||||
#include "StdHelpers.h"
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
|
||||
std::string ReplaceInStr(const std::string& in, const std::string& search_for, const std::string& replace_with) {
|
||||
std::string ret = in;
|
||||
|
||||
std::string::size_type pos = ret.find(search_for);
|
||||
|
||||
while (pos != std::string::npos) {
|
||||
ret = ret.replace(pos, search_for.size(), replace_with);
|
||||
pos = pos - search_for.size() + replace_with.size() + 1;
|
||||
pos = ret.find(search_for, pos);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// std:toupper and std::tolower are overloaded. Well...
|
||||
// http://gcc.gnu.org/ml/libstdc++/2002-11/msg00180.html
|
||||
char toLower_ (char c) { return std::tolower(c); }
|
||||
char toUpper_ (char c) { return std::toupper(c); }
|
||||
|
||||
void ToUpper(std::string& s) {
|
||||
std::transform(s.begin(), s.end(), s.begin(),toUpper_);
|
||||
}
|
||||
|
||||
void ToLower(std::string& s) {
|
||||
std::transform(s.begin(), s.end(), s.begin(),toLower_);
|
||||
}
|
65
WebServer/StdHelpers.h
Normal file
65
WebServer/StdHelpers.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
stdHelpers.h
|
||||
|
||||
Copyright (C) 2002-2005 René Nyffenegger
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||
*/
|
||||
|
||||
/*
|
||||
Note on point 2:
|
||||
THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1
|
||||
*/
|
||||
|
||||
#ifndef STDHELPERS_H__
|
||||
#define STDHELPERS_H__
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
std::string ReplaceInStr(const std::string& in, const std::string& search_for, const std::string& replace_with);
|
||||
|
||||
void ToUpper(std::string& s);
|
||||
void ToLower(std::string& s);
|
||||
|
||||
template <class T>
|
||||
T To(std::string const& s) {
|
||||
T ret;
|
||||
|
||||
std::stringstream stream;
|
||||
stream << s;
|
||||
stream >> ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
std::string StringFrom(T const& t) {
|
||||
std::string ret;
|
||||
|
||||
std::stringstream stream;
|
||||
stream << t;
|
||||
stream >> ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
113
WebServer/Tracer.h
Normal file
113
WebServer/Tracer.h
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
Tracer.h
|
||||
|
||||
Copyright (C) 2002-2004 René Nyffenegger
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
The most current version of Tracer.h can be found at
|
||||
http://www.adp-gmbh.ch/cpp/common/Tracer.html
|
||||
|
||||
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||
*/
|
||||
|
||||
/*
|
||||
Note on point 2:
|
||||
THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1
|
||||
*/
|
||||
|
||||
#ifndef TRACER_H__
|
||||
#define TRACER_H__
|
||||
|
||||
#ifdef DO_TRACE
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define StartTrace(x) TraceFunc_::StartTrace_(x)
|
||||
#define Trace(x) dummy_____for_trace_func______.Trace_(x)
|
||||
#define Trace2(x,y) dummy_____for_trace_func______.Trace_(x,y)
|
||||
#define TraceFunc(x) TraceFunc_ dummy_____for_trace_func______(x)
|
||||
#define TraceFunc2(x,y) TraceFunc_ dummy_____for_trace_func______(x,y)
|
||||
|
||||
class TraceFunc_ {
|
||||
std::string func_name_;
|
||||
public:
|
||||
/*
|
||||
Calling TraceFunc_ indents the output until the enclosing scope ( {...} )
|
||||
is left.
|
||||
*/
|
||||
TraceFunc_(std::string const&);
|
||||
TraceFunc_(std::string const&, std::string const& something);
|
||||
~TraceFunc_();
|
||||
|
||||
/*
|
||||
Creates the trace output file named by filename.
|
||||
Must be called before any other tracing function.
|
||||
Use the StartTrace macro for it.
|
||||
*/
|
||||
static void StartTrace_(std::string const& filename);
|
||||
|
||||
template <class T>
|
||||
void Trace_(T const& t) {
|
||||
DWORD d;
|
||||
std::string indent_s;
|
||||
std::stringstream s;
|
||||
|
||||
s << t;
|
||||
|
||||
for (int i=0; i< indent; i++) indent_s += " ";
|
||||
|
||||
::WriteFile(trace_file_,indent_s.c_str(), indent_s.size(), &d, 0);
|
||||
::WriteFile(trace_file_, s.str().c_str(), s.str().size() ,&d, 0);
|
||||
::WriteFile(trace_file_,"\x0a",1,&d,0);
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
void Trace_(T const& t, U const& u) {
|
||||
std::string indent_s;
|
||||
std::stringstream s;
|
||||
|
||||
s << t;
|
||||
s << u;
|
||||
Trace_(s.str());
|
||||
}
|
||||
|
||||
static int indent;
|
||||
/* trace_file_ is a HANDLE for the file in which the traced output goes.
|
||||
The file is opened (that is, created) by calling StartTrace_.
|
||||
Better yet, use the StartTrace macro
|
||||
to create the file.
|
||||
*/
|
||||
static HANDLE trace_file_;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#define StartTrace(x)
|
||||
#define Trace(x)
|
||||
#define Trace2(x,y)
|
||||
#define TraceFunc(x)
|
||||
#define TraceFunc2(x,y)
|
||||
|
||||
#endif
|
||||
|
||||
#endif // TRACER_H__
|
167
WebServer/UrlHelper.cpp
Normal file
167
WebServer/UrlHelper.cpp
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
UrlHelper.cpp
|
||||
|
||||
Copyright (C) 2002-2004 René Nyffenegger
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||
*/
|
||||
|
||||
/*
|
||||
Note on point 2:
|
||||
THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1
|
||||
*/
|
||||
|
||||
#include "UrlHelper.h"
|
||||
#include "Tracer.h"
|
||||
#include "StdHelpers.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
bool RemoveProtocolFromUrl(std::string const& url, std::string& protocol, std::string& rest) {
|
||||
TraceFunc("RemoveProtocolFromUrl");
|
||||
Trace(std::string("url='")+url+"'");
|
||||
std::string::size_type pos_colon = url.find(":");
|
||||
|
||||
if (pos_colon == std::string::npos) {
|
||||
rest = url;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (url.size() < pos_colon + 2) {
|
||||
rest = url;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (url[pos_colon+1] != '/' ||
|
||||
url[pos_colon+2] != '/') {
|
||||
rest = url;
|
||||
return false;
|
||||
}
|
||||
|
||||
protocol = url.substr(0,pos_colon);
|
||||
rest = url.substr(3+pos_colon); // Skipping three characters ( '://' )
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SplitGetReq(std::string get_req, std::string& path, std::map<std::string, std::string>& params) {
|
||||
TraceFunc("SplitGetReq");
|
||||
|
||||
// Remove trailing newlines
|
||||
if (get_req[get_req.size()-1] == '\x0d' ||
|
||||
get_req[get_req.size()-1] == '\x0a')
|
||||
get_req=get_req.substr(0, get_req.size()-1);
|
||||
|
||||
if (get_req[get_req.size()-1] == '\x0d' ||
|
||||
get_req[get_req.size()-1] == '\x0a')
|
||||
get_req=get_req.substr(0, get_req.size()-1);
|
||||
|
||||
// Remove potential Trailing HTTP/1.x
|
||||
if (get_req.size() > 7) {
|
||||
if (get_req.substr(get_req.size()-8, 7) == "HTTP/1.") {
|
||||
get_req=get_req.substr(0, get_req.size()-9);
|
||||
}
|
||||
}
|
||||
|
||||
std::string::size_type qm = get_req.find("?");
|
||||
if (qm != std::string::npos) {
|
||||
std::string url_params = get_req.substr(qm+1);
|
||||
|
||||
path = get_req.substr(0, qm);
|
||||
|
||||
// Appending a '&' so that there are as many '&' as name-value pairs.
|
||||
// It makes it easier to split the url for name value pairs, he he he
|
||||
url_params += "&";
|
||||
|
||||
std::string::size_type next_amp = url_params.find("&");
|
||||
|
||||
while (next_amp != std::string::npos) {
|
||||
std::string name_value = url_params.substr(0,next_amp);
|
||||
url_params = url_params.substr(next_amp+1);
|
||||
next_amp = url_params.find("&");
|
||||
|
||||
std::string::size_type pos_equal = name_value.find("=");
|
||||
|
||||
std::string nam = name_value.substr(0,pos_equal);
|
||||
std::string val = name_value.substr(pos_equal+1);
|
||||
|
||||
std::string::size_type pos_plus;
|
||||
while ( (pos_plus = val.find("+")) != std::string::npos ) {
|
||||
val.replace(pos_plus, 1, " ");
|
||||
}
|
||||
|
||||
// Replacing %xy notation
|
||||
std::string::size_type pos_hex = 0;
|
||||
while ( (pos_hex = val.find("%", pos_hex)) != std::string::npos ) {
|
||||
std::stringstream h;
|
||||
h << val.substr(pos_hex+1, 2);
|
||||
h << std::hex;
|
||||
|
||||
int i;
|
||||
h>>i;
|
||||
|
||||
std::stringstream f;
|
||||
f << static_cast<char>(i);
|
||||
std::string s;
|
||||
f >> s;
|
||||
|
||||
val.replace(pos_hex, 3, s);
|
||||
pos_hex ++;
|
||||
}
|
||||
|
||||
params.insert(std::map<std::string,std::string>::value_type(nam, val));
|
||||
}
|
||||
}
|
||||
else {
|
||||
path = get_req;
|
||||
}
|
||||
}
|
||||
|
||||
void SplitUrl(std::string const& url, std::string& protocol, std::string& server, std::string& path) {
|
||||
TraceFunc("SplitUrl");
|
||||
RemoveProtocolFromUrl(url, protocol, server);
|
||||
|
||||
if (protocol == "http") {
|
||||
std::string::size_type pos_slash = server.find("/");
|
||||
|
||||
if (pos_slash != std::string::npos) {
|
||||
Trace("slash found");
|
||||
path = server.substr(pos_slash);
|
||||
server = server.substr(0, pos_slash);
|
||||
}
|
||||
else {
|
||||
Trace("slash not found");
|
||||
path = "/";
|
||||
}
|
||||
}
|
||||
else if (protocol == "file") {
|
||||
path = ReplaceInStr(server, "\\", "/");
|
||||
server = "";
|
||||
}
|
||||
else {
|
||||
std::cerr << "unknown protocol in SplitUrl: '" << protocol << "'" << std::endl;
|
||||
}
|
||||
}
|
42
WebServer/UrlHelper.h
Normal file
42
WebServer/UrlHelper.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
UrlHelper.h
|
||||
|
||||
Copyright (C) 2002-2004 René Nyffenegger
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||
*/
|
||||
|
||||
/*
|
||||
Note on point 2:
|
||||
THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1
|
||||
*/
|
||||
#ifndef __URL_HELPER_H__
|
||||
#define __URL_HELPER_H__
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
void SplitUrl (std::string const& url, std::string& protocol, std::string& server, std::string& path);
|
||||
bool RemoveProtocolFromUrl(std::string const& url, std::string& protocol, std::string& rest);
|
||||
|
||||
void SplitGetReq (std::string et_req, std::string& path, std::map<std::string, std::string>& params);
|
||||
|
||||
#endif
|
226
WebServer/WebServer.cpp
Normal file
226
WebServer/WebServer.cpp
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
WebServer.cpp
|
||||
|
||||
Copyright (C) 2003-2007 René Nyffenegger
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||
|
||||
Thanks to Tom Lynn who pointed out an error in this source code.
|
||||
*/
|
||||
|
||||
/*
|
||||
Note on point 2:
|
||||
THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1
|
||||
*/
|
||||
|
||||
#include <ctime>
|
||||
#ifdef _WIN32
|
||||
#include <process.h>
|
||||
#endif
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
#include "WebServer.h"
|
||||
#include "Socket.h"
|
||||
#include "UrlHelper.h"
|
||||
#include "base64.h"
|
||||
|
||||
#include "cEvent.h"
|
||||
|
||||
|
||||
webserver::request_func webserver::request_func_=0;
|
||||
|
||||
#ifdef _WIN32
|
||||
unsigned webserver::Request(void* ptr_s)
|
||||
#else
|
||||
void* webserver::Request(void* ptr_s)
|
||||
#endif
|
||||
{
|
||||
Socket* s = (reinterpret_cast<Socket*>(ptr_s));
|
||||
|
||||
std::string line = s->ReceiveLine();
|
||||
if (line.empty()) {
|
||||
s->Close();
|
||||
delete s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
http_request req;
|
||||
|
||||
if (line.find("GET") == 0) {
|
||||
req.method_="GET";
|
||||
}
|
||||
else if (line.find("POST") == 0) {
|
||||
req.method_="POST";
|
||||
}
|
||||
|
||||
std::string path;
|
||||
std::map<std::string, std::string> params;
|
||||
|
||||
size_t posStartPath = line.find_first_not_of(" ",3);
|
||||
|
||||
SplitGetReq(line.substr(posStartPath), path, params);
|
||||
|
||||
req.status_ = "202 OK";
|
||||
req.s_ = s;
|
||||
req.path_ = path;
|
||||
req.params_ = params;
|
||||
|
||||
static const std::string authorization = "Authorization: Basic ";
|
||||
static const std::string accept = "Accept: " ;
|
||||
static const std::string accept_language = "Accept-Language: " ;
|
||||
static const std::string accept_encoding = "Accept-Encoding: " ;
|
||||
static const std::string user_agent = "User-Agent: " ;
|
||||
|
||||
while(1) {
|
||||
line=s->ReceiveLine();
|
||||
|
||||
if (line.empty()) break;
|
||||
|
||||
unsigned int pos_cr_lf = line.find_first_of("\x0a\x0d");
|
||||
if (pos_cr_lf == 0) break;
|
||||
|
||||
line = line.substr(0,pos_cr_lf);
|
||||
|
||||
if (line.substr(0, authorization.size()) == authorization) {
|
||||
req.authentication_given_ = true;
|
||||
std::string encoded = line.substr(authorization.size());
|
||||
std::string decoded = base64_decode(encoded);
|
||||
|
||||
unsigned int pos_colon = decoded.find(":");
|
||||
|
||||
req.username_ = decoded.substr(0, pos_colon);
|
||||
req.password_ = decoded.substr(pos_colon+1 );
|
||||
}
|
||||
else if (line.substr(0, accept.size()) == accept) {
|
||||
req.accept_ = line.substr(accept.size());
|
||||
}
|
||||
else if (line.substr(0, accept_language.size()) == accept_language) {
|
||||
req.accept_language_ = line.substr(accept_language.size());
|
||||
}
|
||||
else if (line.substr(0, accept_encoding.size()) == accept_encoding) {
|
||||
req.accept_encoding_ = line.substr(accept_encoding.size());
|
||||
}
|
||||
else if (line.substr(0, user_agent.size()) == user_agent) {
|
||||
req.user_agent_ = line.substr(user_agent.size());
|
||||
}
|
||||
}
|
||||
|
||||
request_func_(&req);
|
||||
|
||||
std::stringstream str_str;
|
||||
str_str << req.answer_.size();
|
||||
|
||||
time_t ltime;
|
||||
time(<ime);
|
||||
tm* gmt= gmtime(<ime);
|
||||
|
||||
#ifdef _WIN32
|
||||
static std::string const serverName = "MCServerWebAdmin (Windows)";
|
||||
#elif __APPLE__
|
||||
static std::string const serverName = "MCServerWebAdmin (MacOSX)";
|
||||
#else
|
||||
static std::string const serverName = "MCServerWebAdmin (Linux)";
|
||||
#endif
|
||||
|
||||
|
||||
char* asctime_remove_nl = std::asctime(gmt);
|
||||
asctime_remove_nl[24] = 0;
|
||||
|
||||
s->SendBytes("HTTP/1.1 ");
|
||||
|
||||
if (! req.auth_realm_.empty() ) {
|
||||
s->SendLine("401 Unauthorized");
|
||||
s->SendBytes("WWW-Authenticate: Basic Realm=\"");
|
||||
s->SendBytes(req.auth_realm_);
|
||||
s->SendLine("\"");
|
||||
}
|
||||
else {
|
||||
s->SendLine(req.status_);
|
||||
}
|
||||
s->SendLine(std::string("Date: ") + asctime_remove_nl + " GMT");
|
||||
s->SendLine(std::string("Server: ") +serverName);
|
||||
s->SendLine("Connection: close");
|
||||
s->SendLine("Content-Type: text/html; charset=ISO-8859-1");
|
||||
s->SendLine("Content-Length: " + str_str.str());
|
||||
s->SendLine("");
|
||||
s->SendLine(req.answer_);
|
||||
|
||||
s->Close();
|
||||
delete s;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void webserver::Stop()
|
||||
{
|
||||
m_bStop = true;
|
||||
m_Socket->Close();
|
||||
m_Event->Wait();
|
||||
}
|
||||
|
||||
void webserver::Begin()
|
||||
{
|
||||
m_bStop = false;
|
||||
while ( !m_bStop )
|
||||
{
|
||||
Socket* ptr_s=m_Socket->Accept();
|
||||
if( m_bStop )
|
||||
{
|
||||
if( ptr_s != 0 )
|
||||
{
|
||||
ptr_s->Close();
|
||||
delete ptr_s;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// unused variable 'ret'
|
||||
//_beginthreadex(0,0,Request,(void*) ptr_s,0,&ret);
|
||||
// Thanks to Frank M. Hoffmann for fixing a HANDLE leak
|
||||
#ifdef _WIN32
|
||||
unsigned ret;
|
||||
HANDLE hHandle = reinterpret_cast<HANDLE>(_beginthreadex(0,0,Request,(void*) ptr_s,0,&ret));
|
||||
CloseHandle(hHandle);
|
||||
#else
|
||||
pthread_t* hHandle = new pthread_t;
|
||||
pthread_create( hHandle, NULL, Request, ptr_s);
|
||||
#endif
|
||||
}
|
||||
m_Event->Set();
|
||||
}
|
||||
|
||||
webserver::webserver(unsigned int port_to_listen, request_func r) {
|
||||
m_Socket = new SocketServer(port_to_listen,1);
|
||||
|
||||
request_func_ = r;
|
||||
m_Event = new cEvent();
|
||||
}
|
||||
|
||||
webserver::~webserver()
|
||||
{
|
||||
delete m_Socket;
|
||||
delete m_Event;
|
||||
}
|
95
WebServer/WebServer.h
Normal file
95
WebServer/WebServer.h
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
WebServer.h
|
||||
|
||||
Copyright (C) 2003-2004 René Nyffenegger
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
Note on point 2:
|
||||
THIS IS NOT THE ORIGINAL SOURCE1!!1!!!~!!~`1ONE!!`1
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
class cEvent;
|
||||
class Socket;
|
||||
class SocketServer;
|
||||
class webserver {
|
||||
public:
|
||||
struct http_request {
|
||||
|
||||
http_request()
|
||||
: s_( 0 )
|
||||
, authentication_given_(false)
|
||||
{}
|
||||
|
||||
Socket* s_;
|
||||
std::string method_;
|
||||
std::string path_;
|
||||
std::map<std::string, std::string> params_;
|
||||
|
||||
std::string accept_;
|
||||
std::string accept_language_;
|
||||
std::string accept_encoding_;
|
||||
std::string user_agent_;
|
||||
|
||||
/* status_: used to transmit server's error status, such as
|
||||
o 202 OK
|
||||
o 404 Not Found
|
||||
and so on */
|
||||
std::string status_;
|
||||
|
||||
/* auth_realm_: allows to set the basic realm for an authentication,
|
||||
no need to additionally set status_ if set */
|
||||
std::string auth_realm_;
|
||||
|
||||
std::string answer_;
|
||||
|
||||
/* authentication_given_ is true when the user has entered a username and password.
|
||||
These can then be read from username_ and password_ */
|
||||
bool authentication_given_;
|
||||
std::string username_;
|
||||
std::string password_;
|
||||
};
|
||||
|
||||
typedef void (*request_func) (http_request*);
|
||||
webserver(unsigned int port_to_listen, request_func);
|
||||
~webserver();
|
||||
|
||||
void Begin();
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
bool m_bStop;
|
||||
#ifdef _WIN32
|
||||
static unsigned __stdcall Request(void*);
|
||||
#else
|
||||
static void* Request(void*);
|
||||
#endif
|
||||
static request_func request_func_;
|
||||
|
||||
cEvent* m_Event;
|
||||
SocketServer* m_Socket;
|
||||
};
|
96
WebServer/base64.cpp
Normal file
96
WebServer/base64.cpp
Normal file
@ -0,0 +1,96 @@
|
||||
#include "base64.h"
|
||||
#include <iostream>
|
||||
|
||||
static const std::string base64_chars =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
|
||||
static inline bool is_base64(unsigned char c) {
|
||||
return (isalnum(c) || (c == '+') || (c == '/'));
|
||||
}
|
||||
|
||||
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
|
||||
std::string ret;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
unsigned char char_array_3[3];
|
||||
unsigned char char_array_4[4];
|
||||
|
||||
while (in_len--) {
|
||||
char_array_3[i++] = *(bytes_to_encode++);
|
||||
if (i == 3) {
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for(i = 0; (i <4) ; i++)
|
||||
ret += base64_chars[char_array_4[i]];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i)
|
||||
{
|
||||
for(j = i; j < 3; j++)
|
||||
char_array_3[j] = '\0';
|
||||
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for (j = 0; (j < i + 1); j++)
|
||||
ret += base64_chars[char_array_4[j]];
|
||||
|
||||
while((i++ < 3))
|
||||
ret += '=';
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
std::string base64_decode(std::string const& encoded_string) {
|
||||
int in_len = encoded_string.size();
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int in_ = 0;
|
||||
unsigned char char_array_4[4], char_array_3[3];
|
||||
std::string ret;
|
||||
|
||||
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
||||
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||
if (i ==4) {
|
||||
for (i = 0; i <4; i++)
|
||||
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for (i = 0; (i < 3); i++)
|
||||
ret += char_array_3[i];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j <4; j++)
|
||||
char_array_4[j] = 0;
|
||||
|
||||
for (j = 0; j <4; j++)
|
||||
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
4
WebServer/base64.h
Normal file
4
WebServer/base64.h
Normal file
@ -0,0 +1,4 @@
|
||||
#include <string>
|
||||
|
||||
std::string base64_encode(unsigned char const* , unsigned int len);
|
||||
std::string base64_decode(std::string const& s);
|
112
WebServer/cEvent.cpp
Normal file
112
WebServer/cEvent.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
#include "cEvent.h"
|
||||
#include "../source/cMCLogger.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h> // sprintf()
|
||||
#endif
|
||||
|
||||
cEvent::cEvent( unsigned int a_NumEvents /* = 1 */ )
|
||||
: m_NumEvents( a_NumEvents )
|
||||
#ifndef _WIN32
|
||||
, m_bNamed( false )
|
||||
#endif
|
||||
{
|
||||
if( m_NumEvents < 1 ) m_NumEvents = 1;
|
||||
|
||||
#ifdef _WIN32
|
||||
m_Handle = new HANDLE[ m_NumEvents ];
|
||||
for( unsigned int i = 0; i < m_NumEvents; i++)
|
||||
{
|
||||
((HANDLE*)m_Handle)[i] = CreateEvent( 0, FALSE, FALSE, 0 );
|
||||
}
|
||||
#else
|
||||
m_Handle = new sem_t*[ m_NumEvents ];
|
||||
for( unsigned int i = 0; i < m_NumEvents; i++)
|
||||
{
|
||||
|
||||
sem_t* & HandlePtr = ((sem_t**)m_Handle)[i];
|
||||
HandlePtr = new sem_t;
|
||||
|
||||
if( sem_init( HandlePtr, 0, 0 ) )
|
||||
{
|
||||
LOG("WARNING cEvent: Could not create unnamed semaphore, fallback to named.");
|
||||
m_bNamed = true;
|
||||
delete HandlePtr; // named semaphores return their own address
|
||||
|
||||
char c_Str[32];
|
||||
sprintf( c_Str, "cEvent%p", &HandlePtr );
|
||||
HandlePtr = sem_open( c_Str, O_CREAT, 777, 0 );
|
||||
if( HandlePtr == SEM_FAILED )
|
||||
LOG("ERROR: Could not create Event. (%i)", errno);
|
||||
else
|
||||
if( sem_unlink( c_Str ) != 0 )
|
||||
LOG("ERROR: Could not unlink cEvent. (%i)", errno);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
cEvent::~cEvent()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
for( unsigned int i = 0; i < m_NumEvents; i++ )
|
||||
{
|
||||
CloseHandle( ((HANDLE*)m_Handle)[i] );
|
||||
}
|
||||
delete [] (HANDLE*)m_Handle;
|
||||
#else
|
||||
for( unsigned int i = 0; i < m_NumEvents; i++ )
|
||||
{
|
||||
if( m_bNamed )
|
||||
{
|
||||
sem_t* & HandlePtr = ((sem_t**)m_Handle)[i];
|
||||
char c_Str[32];
|
||||
sprintf( c_Str, "cEvent%p", &HandlePtr );
|
||||
// LOG("Closing event: %s", c_Str );
|
||||
// LOG("Sem ptr: %p", HandlePtr );
|
||||
if( sem_close( HandlePtr ) != 0 )
|
||||
{
|
||||
LOG("ERROR: Could not close cEvent. (%i)", errno);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sem_destroy( ((sem_t**)m_Handle)[i] );
|
||||
delete ((sem_t**)m_Handle)[i];
|
||||
}
|
||||
}
|
||||
delete [] (sem_t**)m_Handle; m_Handle = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void cEvent::Wait()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
WaitForMultipleObjects( m_NumEvents, (HANDLE*)m_Handle, true, INFINITE );
|
||||
#else
|
||||
for(unsigned int i = 0; i < m_NumEvents; i++)
|
||||
{
|
||||
if( sem_wait( ((sem_t**)m_Handle)[i] ) != 0 )
|
||||
{
|
||||
LOG("ERROR: Could not wait for cEvent. (%i)", errno);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void cEvent::Set(unsigned int a_EventNum /* = 0 */)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
SetEvent( ((HANDLE*)m_Handle)[a_EventNum] );
|
||||
#else
|
||||
if( sem_post( ((sem_t**)m_Handle)[a_EventNum] ) != 0 )
|
||||
{
|
||||
LOG("ERROR: Could not set cEvent. (%i)", errno);
|
||||
}
|
||||
#endif
|
||||
}
|
18
WebServer/cEvent.h
Normal file
18
WebServer/cEvent.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
class cEvent
|
||||
{
|
||||
public:
|
||||
cEvent( unsigned int a_NumEvents = 1 );
|
||||
~cEvent();
|
||||
|
||||
void Wait();
|
||||
void Set(unsigned int a_EventNum = 0);
|
||||
private:
|
||||
unsigned int m_NumEvents;
|
||||
void* m_Handle; // HANDLE[] pointer
|
||||
|
||||
#ifndef _WIN32
|
||||
bool m_bNamed;
|
||||
#endif
|
||||
};
|
507
iniFile/iniFile.cpp
Normal file
507
iniFile/iniFile.cpp
Normal file
@ -0,0 +1,507 @@
|
||||
// IniFile.cpp: Implementation of the CIniFile class.
|
||||
// Written by: Adam Clauss
|
||||
// Email: cabadam@houston.rr.com
|
||||
// You may use this class/code as you wish in your programs. Feel free to distribute it, and
|
||||
// email suggested changes to me.
|
||||
//
|
||||
// Rewritten by: Shane Hill
|
||||
// Date: 21/08/2001
|
||||
// Email: Shane.Hill@dsto.defence.gov.au
|
||||
// Reason: Remove dependancy on MFC. Code should compile on any
|
||||
// platform.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
!! MODIFIED BY FAKETRUTH !!
|
||||
*/
|
||||
|
||||
// C++ Includes
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <strstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// C Includes
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
// Local Includes
|
||||
#include "iniFile.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
#define iniEOL endl
|
||||
#else
|
||||
#define iniEOL '\r' << endl
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#define sprintf_s(buffer, buffer_size, stringbuffer, ...) (sprintf(buffer, stringbuffer, __VA_ARGS__))
|
||||
#define vsprintf_s(buffer, stringbuffer, ...) (vsprintf(buffer, stringbuffer, __VA_ARGS__))
|
||||
#define sscanf_s(buffer, stringbuffer, ...) (sscanf(buffer, stringbuffer, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
cIniFile::cIniFile( const string iniPath)
|
||||
{
|
||||
Path( iniPath);
|
||||
caseInsensitive = true;
|
||||
}
|
||||
|
||||
bool cIniFile::ReadFile()
|
||||
{
|
||||
// Normally you would use ifstream, but the SGI CC compiler has
|
||||
// a few bugs with ifstream. So ... fstream used.
|
||||
fstream f;
|
||||