diff --git a/include/isamrpc.cpp b/include/isamrpc.cpp new file mode 100755 index 000000000..c48b6da8c --- /dev/null +++ b/include/isamrpc.cpp @@ -0,0 +1,269 @@ +#include + +#include +#include + +#define NO_MFC +#define CObject TObject +#define CString TString +#define CStringArray TString_array +#include + +static TSocketClient* _client = NULL; + +static DWORD _connection = 0; + +bool rpc_Start() +{ + bool ok = TRUE; + if (_client == NULL) + { + _client = new TSocketClient; + if (!_client->IsOk()) + { + delete _client; + _client = NULL; + ok = error_box("Errore di inizializzazione del client."); + } + } + return ok; +} + +bool rpc_Stop() +{ + if (_client) + { + delete _client; + _client = NULL; + _connection = 0; + } + return TRUE; +} + +bool rpc_Call(const char* cmd) +{ + CHECK(_connection, "Server not connected"); + bool ok = _client->Execute(_connection, cmd); + return ok; +} + +char* rpc_Request(const char* cmd, DWORD& size, real& total) +{ + CHECK(_connection, "Server not connected"); + const clock_t start = clock(); + _client->Request(_connection, cmd); + total = (clock() - start) / double(CLOCKS_PER_SEC); + char* buff = (char*)_client->GetBuffer(size); + return buff; +} + +static TString256 _rpc_call; +static TString _rpc_string; + +inline bool BoolCall() +{ + CHECK(_connection, "Server not connected"); + BOOL yes; + bool ok = _client->RequestBool(_connection, _rpc_call, yes); + if (!ok) + { +#ifndef DBG + yesnofatal_box("RPC call failed: %s", (const char*)_rpc_call); +#endif + yes = FALSE; + } + return yes ? TRUE : FALSE; +} + +inline long IntCall() +{ + CHECK(_connection, "Server not connected"); + long n; + bool ok = _client->RequestInteger(_connection, _rpc_call, n); + if (!ok) + { +#ifndef DBG + yesnofatal_box("RPC call failed: %s", (const char*)_rpc_call); +#endif + n = 0; + } + return n; +} + +inline TString& StrCall() +{ + CHECK(_connection, "Server not connected"); + bool ok = _client->RequestString(_connection, _rpc_call, _rpc_string); + if (!ok) + { +#ifndef DBG + yesnofatal_box("RPC call failed: %s", (const char*)_rpc_call); +#endif + _rpc_string.cut(0); + } + return _rpc_string; +} + +inline bool BoolCallInt(const char* fn, long n) +{ + _rpc_call.format("%s(%ld)", fn, n); + return BoolCall(); +} + +inline long IntCallInt(const char* fn, long n) +{ + _rpc_call.format("%s(%ld)", fn, n); + return IntCall(); +} + +inline long IntCallIntInt(const char* fn, long n, long k) +{ + _rpc_call.format("%s(%ld,%ld)", fn, n, k); + return IntCall(); +} + +inline long IntCallIntIntInt(const char* fn, long n, long k, long f) +{ + _rpc_call.format("%s(%ld,%ld,%ld)", fn, n, k, f); + return IntCall(); +} + + +inline long IntCallIntIntStr(const char* fn, long n, long k, const char* str) +{ + _rpc_call.format("%s(%ld,%ld,|%s|)", fn, n, k, str); + return IntCall(); +} + +inline long IntCallIntStr(const char* fn, long n, const char* str) +{ + _rpc_call.format("%s(%ld,|%s|)", fn, n, str); + return IntCall(); +} + +inline int IntCallIntStrInt(const char* fn, long n, const char* s, long f) +{ + _rpc_call.format("%s(%ld,|%s|,%ld)", fn, n, s, f); + return (int)IntCall(); +} + +inline long IntCallIntStrStr(const char* fn, long n, const char* str, const char* val) +{ + _rpc_call.format("%s(%ld,|%s|,|%s|)", fn, n, str, val); + return IntCall(); +} + +inline long IntCallStr(const char* fn, const char* str) +{ + _rpc_call.format("%s(%s)", fn, str); + return IntCall(); +} + + +inline TString& StrCallIntInt(const char* fn, long n, long k) +{ + _rpc_call.format("%s(%ld,%ld)", fn, n, k); + return StrCall(); +} + +inline TString& StrCallIntStr(const char* fn, long n, const char* str) +{ + _rpc_call.format("%s(%ld,|%s|)", fn, n, str); + return StrCall(); +} + +bool rpc_DongleHasModule(word af) +{ + return BoolCallInt("DongleHasModule", af); +} + +bool rpc_DongleModules(word* int_tab0) +{ + DWORD size; + real time; + char* buff = rpc_Request("DongleModules()", size, time); + if (buff) + memcpy(int_tab0, buff, (size_t)size); + return size > 0; +} + +unsigned rpc_DongleNumber() +{ + _rpc_call = "DongleNumber()"; + return (unsigned)IntCall(); +} + +bool rpc_UserLogin(const char* server, const char* user, + const char* password, const char* application) +{ + if (_client == NULL) + { + if (!rpc_Start()) + return FALSE; + } + + const bool local = server == NULL || *server == '\0'; + TString name(40); + if (local) + name = "locale"; + else + name = server; + const char* str = (const char*)name; + + TString80 error; + + if (_connection != 0) + _client->RemoveConnection(_connection); + + _connection = _client->QueryConnection("1883", server); + + if (_connection) + { + TString cmd(32); + cmd << "UserLogin(" << user << ")"; + + _rpc_call.format("UserLogin(%s,%s,%s)", user, password, application); + BOOL logged = FALSE; + bool connected = _client->RequestBool(_connection, _rpc_call, logged); + if (connected) + { + if (!logged) + { + connected = FALSE; + error.format("La connessione di %s e' stata rifiutata dal Server %s", (const char*)user, str); + } + } + else + { + error.format("Impossibile connettersi al Server %s", str); + } + + if (!connected) + { + _client->RemoveConnection(_connection); + _connection = 0; + } + } + else + { + error.format("Impossibile connettersi al Server %s", str); + } + + if (error.not_empty()) + error_box(error); + + return _connection != 0; +} + +bool rpc_UserLogout() +{ + if (_connection) + { + rpc_Call("UserLogout()"); + _client->RemoveConnection(_connection); + _connection = 0; + } + + return TRUE; +} + diff --git a/include/isamrpc.h b/include/isamrpc.h new file mode 100755 index 000000000..5e7b21c18 --- /dev/null +++ b/include/isamrpc.h @@ -0,0 +1,23 @@ +#ifndef __ISAMRPC_H +#define __ISAMRPC_H + +#ifndef __REAL_H +#include +#endif + +bool rpc_Call(const char* cmd); +char* rpc_Request(const char* cmd, unsigned long& size, real& time); + +bool rpc_DongleHasModule(word af); +bool rpc_DongleModules(word* int_tab0); +word rpc_DongleNumber(); + +bool rpc_UserLogin(const char* server, const char* user, + const char* password, const char* application); +bool rpc_UserLogout(); + + +bool rpc_Start(); +bool rpc_Stop(); + +#endif diff --git a/include/netutils.cpp b/include/netutils.cpp new file mode 100755 index 000000000..fab02f47d --- /dev/null +++ b/include/netutils.cpp @@ -0,0 +1,377 @@ +#define NO_MFC +#define CObject TObject +#define CString TString +#define CStringArray TString_array + +#include "NetUtils.h" + +OsType GetOsType() +{ + OsType ver; + + DWORD dwVersion = GetVersion(); + + if (dwVersion < 0x80000000) + ver = WINDOWS_NT; + else + { + if (LOBYTE(LOWORD(dwVersion)) < 4) + ver = WINDOWS_31; + else + ver = WINDOWS_95; + } + return ver; +} + +TLanManager::TLanManager() +{ } + +TLanManager::~TLanManager() +{ + RemoveAllConnections(); +} + +TConnection* TLanManager::OnCreateConnection(DWORD id) +{ + return new TConnection(this, id); +} + +BOOL TLanManager::HasConnections() const +{ +#ifdef NO_MFC + return m_mapConn.items() > 0; +#else + return m_mapConn.GetCount() > 0; +#endif +} + + +BOOL TLanManager::Request(DWORD id, const char* cmd) +{ + TConnection* conn = GetConnection(id) ; + return conn ? conn->Request(cmd) : FALSE; +} + +BOOL TLanManager::Execute(DWORD id, const char* cmd) +{ + TConnection* conn = GetConnection(id) ; + return conn ? conn->Execute(cmd) : FALSE; +} + +// Physically disconnect +BOOL TLanManager::OnRemoveConnection(DWORD id) +{ + return id != NULL; +} + +DWORD TLanManager::AddConnection(TConnection* pConn) +{ + DWORD id = 0; + if (pConn) + { + id = pConn->Id(); +#ifdef NO_MFC + TString16 key; key.format("%lu", id); + m_mapConn.add(key, pConn, TRUE); +#else + TConnection* c; + BOOL ok = m_mapConn.Lookup(id, c); + if (ok) + delete c; + m_mapConn.SetAt(id, pConn); +#endif + } + return id; +} + +BOOL TLanManager::RemoveConnection(DWORD id) +{ + TConnection* pConn = GetConnection(id); + BOOL ok = FALSE; + if (pConn != NULL && OnRemoveConnection(id)) + { +#ifdef NO_MFC + TString16 key; key.format("%lu", id); + m_mapConn.remove(key); +#else + delete pConn; + VERIFY(m_mapConn.RemoveKey(id)); +#endif + ok = TRUE; + } + + return ok; +} + +void TLanManager::RemoveAllConnections() +{ + TConnection* pConn; + +#ifdef NO_MFC + m_mapConn.restart(); + for (pConn = (TConnection*)m_mapConn.get(); pConn; pConn = (TConnection*)m_mapConn.get()) + OnRemoveConnection(pConn->Id()); + m_mapConn.destroy(); +#else + for (POSITION pos = m_mapConn.GetStartPosition(); pos != NULL;) + { + DWORD key; + m_mapConn.GetNextAssoc(pos, key, pConn); + { + OnRemoveConnection(pConn->Id()); + delete pConn; + } + } + m_mapConn.RemoveAll(); +#endif +} + +TConnection* TLanManager::GetConnection(DWORD id) const +{ + TConnection* pConn = NULL; +#ifdef NO_MFC + TString16 key; key.format("%lu", id); + pConn = (TConnection*)m_mapConn.objptr(key); +#else + m_mapConn.Lookup(id, pConn); +#endif + return pConn; +} + +int TLanManager::ForEachConnection(ConnectionFunction f, void* pJolly) +{ + int result = 0; + TConnection* pConn; + +#ifdef NO_MFC + m_mapConn.restart(); + for (pConn = (TConnection*)m_mapConn.get(); + pConn != NULL; + pConn = (TConnection*)m_mapConn.get()) + result += f(*pConn, pJolly); +#else + DWORD key; + for (POSITION pos = m_mapConn.GetStartPosition(); pos != NULL; ) + { + m_mapConn.GetNextAssoc(pos, key, pConn); + result += f(*pConn, pJolly); + } +#endif + + return result; +} + +/////////////////////////////////////////////////////////// +// TLanServer +/////////////////////////////////////////////////////////// + +BYTE* TLanServer::GetBufferSetString(const char* str) +{ + if (str == NULL) + str = ""; + const size_t dwSize = strlen(str)+1; + BYTE* buff = GetBuffer(dwSize); + memcpy(buff, str, dwSize); + return buff; +} + +BYTE* TLanServer::GetBufferSetBool(BOOL n) +{ + const size_t dwSize = sizeof(DWORD); + BYTE* buff = GetBuffer(dwSize); + *(DWORD*)buff = n ? -1 : 0; + return buff; +} + +BYTE* TLanServer::GetBufferSetInteger(long n) +{ + const size_t dwSize = sizeof(DWORD); + BYTE* buff = GetBuffer(dwSize); + *(DWORD*)buff = n; + return buff; +} + + +/////////////////////////////////////////////////////////// +// TLanClient +/////////////////////////////////////////////////////////// + +DWORD TLanClient::QueryConnection(const char* service, + const char* server) +{ + TConnection* pConn = OnQueryConnection(service, server); + return AddConnection(pConn) ; +} + +BOOL TLanClient::Execute(DWORD id, const char* cmd) +{ + return FALSE; +} + +BOOL TLanClient::Request(DWORD id, const char* cmd) +{ + return FALSE; +} + +BOOL TLanClient::RequestString(DWORD id, const char* cmd, CString& res) +{ + BOOL valid = Request(id, cmd); + if (valid) + { + DWORD dwSize; + BYTE* pData = GetBuffer(dwSize); +#ifdef NO_MFC + char* ptr = res.get_buffer((int)dwSize); + memcpy(ptr, pData, (size_t)dwSize); +#else + char* ptr = res.GetBuffer((int)dwSize); + memcpy(ptr, pData, dwSize); + res.ReleaseBuffer(); +#endif + ReleaseBuffer(); + } + return valid; +} + +BOOL TLanClient::RequestInteger(DWORD id, const char* cmd, long& num) +{ + BOOL valid = Request(id, cmd); + if (valid) + { + DWORD dwSize; + BYTE* pData = GetBuffer(dwSize); + num = *(long*)pData; + ReleaseBuffer(); + } + return valid; +} + + +BOOL TLanClient::RequestBool(DWORD id, const char* cmd, BOOL& ok) +{ + BOOL valid = Request(id, cmd); + if (valid) + { + DWORD dwSize; + BYTE* pData = GetBuffer(dwSize); + ok = *(DWORD*)pData != 0; + ReleaseBuffer(); + } + return valid; +} + +/////////////////////////////////////////////////////////// +// TConnection +/////////////////////////////////////////////////////////// + +TConnection::TConnection(TLanManager* pManager, DWORD id) + : m_pManager(pManager), m_dwId(id) +{ +} + +TConnection::~TConnection() +{ +} + +TLanServer& TConnection::Server() const +{ +#ifdef NO_MFC + CHECK(Manager().IsServer(), "Can't cast client to server"); +#else + ASSERT(Manager().IsServer()); +#endif + return (TLanServer&)Manager(); +} + +int TConnection::ParseCommand(const char* cmd, CStringArray& argv) +{ +#ifdef NO_MFC + argv.destroy(); +#else + argv.RemoveAll(); +#endif + + BOOL is_quoted = FALSE; + char end_quote = '\0'; + CString token; + const char* token_start = NULL; + + for (char* c = (char*)cmd; *c; c++) + { + if (end_quote) + { + if (*c == end_quote) + { + *c = '\0'; + token = token_start; + *c = end_quote; + end_quote = '\0'; + is_quoted = TRUE; + } + continue; + } + + if (*c == '(' || *c == ')' || *c == ',') + { + if (token_start) + { + if (is_quoted) + { + } + else + { + const char old = *c; + *c = '\0'; + token = token_start; + *c = old; +#ifdef NO_MFC + token.rtrim(); +#else + token.TrimRight(); +#endif + } + } + +#ifdef NO_MFC + argv.add(token); +#else + argv.Add(token); +#endif + + token_start = NULL; + token = ""; + is_quoted = FALSE; + continue; + } + + if (*c == '"' || *c == '\'' || *c == '|' || BYTE(*c) >= 254) + { + end_quote = *c; + token_start = c+1; + } + + if (token_start == NULL && *c > ' ') + { + token_start = c; + } + } + +#ifdef NO_MFC + return argv.items(); +#else + return argv.GetSize(); +#endif +} + +BOOL TConnection::Execute(const char* cmd) +{ + CStringArray argv; + return ParseCommand(cmd, argv) > 0; +} + +BOOL TConnection::Request(const char* cmd) +{ + CStringArray argv; + return ParseCommand(cmd, argv) > 0; +} + diff --git a/include/netutils.h b/include/netutils.h new file mode 100755 index 000000000..dcefe3c3e --- /dev/null +++ b/include/netutils.h @@ -0,0 +1,115 @@ +#ifndef __NETUTILS_H__ +#define __NETUTILS_H__ + +#ifdef NO_MFC +#define STRICT +#include +#include "assoc.h" +#endif + +class TConnection; + +typedef int (*ConnectionFunction)(TConnection& conn, void* pJolly); + +class TLanManager : public CObject +{ +#ifdef NO_MFC + TAssoc_array m_mapConn; +#else + CMap m_mapConn; +#endif + +protected: + DWORD AddConnection(TConnection* pConn); + + virtual TConnection* OnCreateConnection(DWORD id); + virtual BOOL OnRemoveConnection(DWORD id); + +public: + virtual BOOL IsServer() const { return FALSE; } + virtual BOOL IsClient() const { return FALSE; } + virtual BOOL IsOk() const { return FALSE; } + + virtual BOOL Execute(DWORD id, const char* cmd); + virtual BOOL Request(DWORD id, const char* cmd); + + int ForEachConnection(ConnectionFunction f, void* pJolly); + + BOOL HasConnections() const; + TConnection* GetConnection(DWORD id) const; + + BOOL RemoveConnection(DWORD id); + void RemoveAllConnections(); + + TLanManager(); + virtual ~TLanManager(); +}; + +class TLanServer : public TLanManager +{ + CString m_strName; + +public: + const CString& Name() const { return m_strName; } + + virtual BOOL IsServer() const { return TRUE; } + + virtual BYTE* GetBuffer(DWORD dwSize) = 0; + BYTE* GetBufferSetString(const char* str); + BYTE* GetBufferSetBool(BOOL ok); + BYTE* GetBufferSetInteger(long n); + + TLanServer(const char* name) : m_strName(name) { } + virtual ~TLanServer() { } +}; + +class TLanClient : public TLanManager +{ +protected: + virtual TConnection* OnQueryConnection(const char* service, + const char* server) = 0; +public: + virtual BOOL IsClient() const { return TRUE; } + + DWORD QueryConnection(const char* service, + const char* server = NULL); + + virtual BOOL Execute(DWORD id, const char* cmd); + virtual BOOL Request(DWORD id, const char* cmd); + virtual BYTE* GetBuffer(DWORD& dwSize) = 0; + virtual void ReleaseBuffer() = 0; + + BOOL RequestString(DWORD id, const char* cmd, CString& res); + BOOL RequestInteger(DWORD id, const char* cmd, long& num); + BOOL RequestBool(DWORD id, const char* cmd, BOOL& ok); +}; + +class TConnection : public CObject +{ + TLanManager* m_pManager; + DWORD m_dwId; + +protected: + int ParseCommand(const char* cmd, CStringArray& argv); + +public: + DWORD Id() const { return m_dwId; } + + TLanManager& Manager() const { return *m_pManager; } + TLanServer& Server() const; + + virtual BOOL Execute(const char* cmd); + virtual BOOL Request(const char* cmd); + + BOOL ReturnBool(int b) const { return Server().GetBufferSetBool(b) != NULL; } + BOOL ReturnInteger(long n) const { return Server().GetBufferSetInteger(n) != NULL; } + BOOL ReturnString(const CString& s) const { return Server().GetBufferSetString(s) != NULL; } + + TConnection(TLanManager* lm, DWORD id); + virtual ~TConnection(); +}; + +enum OsType { WINDOWS_31, WINDOWS_95, WINDOWS_NT }; +OsType GetOsType(); + +#endif