#include #include #include #include static TSocketClient* _client = NULL; static CONNID _connection = 0; bool rpc_Start() { bool ok = true; if (_client == NULL) { srand(clock()); _client = new TSocketClient; if (!_client->IsOk()) { delete _client; _client = NULL; ok = error_box(TR("Errore di inizializzazione del socket 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) != 0; return ok; } int rpc_Timeout(int sec) { CHECK(_client != NULL, "Client not initialized"); const int to = _client->Timeout(); if (sec >= 0) _client->SetTimeout(sec); return to; } char* rpc_Request(const char* cmd, size_t& 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 TString _rpc_call(256); static TString _rpc_string; static bool BoolCall(int timeout = 0) { CHECK(_connection, "Server not connected"); bool yes = false; bool ok = false; if (timeout > 0) { const int to = rpc_Timeout(timeout); ok = _client->RequestBool(_connection, _rpc_call, yes); rpc_Timeout(to); } else 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; } static long IntCall(int timeout = 0) { CHECK(_connection, "Server not connected"); long n = 0; bool ok = false; if (timeout > 0) { const int to = rpc_Timeout(timeout); ok = _client->RequestInteger(_connection, _rpc_call, n) != 0; rpc_Timeout(to); } else ok = _client->RequestInteger(_connection, _rpc_call, n) != 0; if (!ok) { #ifndef DBG yesnofatal_box("RPC call failed: %s", (const char*)_rpc_call); #endif n = 0; } return n; } static TString& StrCall() { CHECK(_connection, "Server not connected"); bool ok = _client->RequestString(_connection, _rpc_call, _rpc_string) != 0; if (!ok) { #ifndef DBG yesnofatal_box("RPC call failed: %s", (const char*)_rpc_call); #endif _rpc_string.cut(0); } return _rpc_string; } static bool BoolCallInt(const char* fn, long n) { _rpc_call.format("%s(%ld)", fn, n); return BoolCall(); } static long IntCallInt(const char* fn, long n) { _rpc_call.format("%s(%ld)", fn, n); return IntCall(); } static long IntCallIntInt(const char* fn, long n, long k) { _rpc_call.format("%s(%ld,%ld)", fn, n, k); return IntCall(); } static long IntCallIntIntInt(const char* fn, long n, long k, long f) { _rpc_call.format("%s(%ld,%ld,%ld)", fn, n, k, f); return IntCall(); } static 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(); } static long IntCallIntStr(const char* fn, long n, const char* str) { _rpc_call.format("%s(%ld,|%s|)", fn, n, str); return IntCall(); } static 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(); } static 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(); } static long IntCallStr(const char* fn, const char* str) { _rpc_call.format("%s(%s)", fn, str); return IntCall(); } static TString& StrCallIntInt(const char* fn, long n, long k) { _rpc_call.format("%s(%ld,%ld)", fn, n, k); return StrCall(); } static 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(TBit_array& ba) { size_t size; real time; word* buff = (word*)rpc_Request("DongleModules()", size, time); if (buff && size > 0) { ba.reset(); ba.set(0, true); const int words = int(size/2); int module = 1; for (int i = 0; i < words; i++) { for (int b = 0; b < 16; b++) { if (buff[i] & (1 << b)) ba.set(module, true); module++; } } } return size > 0; } unsigned rpc_DongleNumber() { _rpc_call = "DongleNumber()"; return (unsigned)IntCall(5); } unsigned rpc_DongleYear() { _rpc_call = "DongleYear()"; return (unsigned)IntCall(5); } bool rpc_DongleInfo(word& number, word& year, TBit_array& ba) { size_t size; real time; number = year = 0; ba.reset(); ba.set(0, true); const int to = rpc_Timeout(5); // change timeout word* buff = (word*)rpc_Request("DongleInfo()", size, time); rpc_Timeout(to); // restore timeout if (buff && size > 4) { number = buff[0]; year = buff[1]; const int words = int(size/2); int module = 1; for (int i = 2; i < words; i++) { for (int b = 0; b < 16; b++) { if (buff[i] & (1 << b)) ba.set(module, true); module++; } } } return (number >= 0) && (year > 2000); } static unsigned int create_password(TString& pass) { const int BASE = 19; unsigned int num = 0; const struct tm* t = xvt_time_now(); srand(t->tm_hour * 10000 + t->tm_min *100 + t->tm_sec); do { num = 883*rand(); while (num % 883 != 0) // Possible overflow num++; pass.cut(0); char str[2] = { '\0', '\0' }; while (num > 0) { unsigned int k = num % BASE; if (k < 10) str[0] = '0'+k; else str[0] = 'A'+k-10; num /= BASE; pass.insert(str); } } while (pass.len() < 5); return num; } bool rpc_UserLogin(const char* server, const char* user, const char* dummy_password, const char* application) { if (_client == NULL) { if (!rpc_Start()) return false; } const bool local = server == NULL || *server == '\0' || xvt_str_same(server, "127.0.0.1") || xvt_str_same(server, "localhost"); TString80 name; if (local) xvt_sys_get_host_name(name.get_buffer(), name.size()); else name = server; if (_connection != 0) _client->RemoveConnection(_connection); _connection = _client->QueryConnection("1883", server); TString error; if (_connection) { TString16 password; create_password(password); const int session = xvt_sys_get_session_id(); _rpc_call.format("UserLogin(%s,%s,%s,%d)", user, (const char*)password, application, session); long answer = 0; bool connected = _client->RequestInteger(_connection, _rpc_call, answer) != 0; if (connected) { const bool logged = (answer == 1) || ((answer % 883 == 0) && (answer != 0)); if (!logged) { connected = false; error.format(FR("La connessione di %s e' stata rifiutata dal Server %s"), (const char*)user, (const char*)name); } } else { error.format(FR("Impossibile connettersi al Server %s"), (const char*)name); } if (!connected) { _client->RemoveConnection(_connection); _connection = 0; } } else { if (!local) error.format(FR("Impossibile connettersi al Server %s"), (const char*)name); } if (error.not_empty()) error_box(error); return _connection != 0; } bool rpc_UserLogout(const char* appname) { if (_connection) { const int session = xvt_sys_get_session_id(); _rpc_call.format("UserLogout(%s,%d,%s)", (const char*)user(), session, appname); //rpc_Call(_rpc_call); // Richiede il logout senza attendere la risposta BoolCall(3); // Aspetta un po' in modo da permettere al server di esaminare la richiesta _client->RemoveConnection(_connection); // Chiude la connessione _connection = 0; } return true; } bool rpc_DongleModuleActivate(word mod, bool on) { TString16 password; create_password(password); _rpc_call.format("DongleModuleActivate(%d,%d,%s)", mod, on, (const char*)password); return BoolCall(); } bool rpc_DongleUsersActivate(word users) { TString16 password; create_password(password); _rpc_call.format("DongleUsersActivate(%d,%s)", users, (const char*)password); return BoolCall(); } bool rpc_DongleYearActivate(word year) { TString16 password; create_password(password); _rpc_call.format("DongleYearActivate(%d,%s)", year, (const char*)password); return BoolCall(); } bool http_isredirected_server(TString& server, TFilename& remote_file, const char* authorization) { TSocketClient client; if (!client.IsOk()) return error_box(TR("Impossibile inizializzare il client HTTP")); CONNID connection = client.QueryConnection("80", server); bool ok = connection != 0; if (ok) { ok = client.HttpIsRedirectedServer(connection, server, remote_file, authorization) != 0; client.RemoveConnection(connection); } return ok; } bool http_get(const char* server, const char* remote_file, const char* local_file, const char* authorization) { TSocketClient client; if (!client.IsOk()) return error_box(TR("Impossibile inizializzare il client HTTP")); CONNID connection = client.QueryConnection("80", server); bool ok = connection != 0; if (ok) { ok = client.HttpGetFile(connection, remote_file, local_file, authorization) != 0; client.RemoveConnection(connection); } return ok; } bool http_dir(const char* server, const char* remote_dir, TString_array& list) { TSocketClient client; if (!client.IsOk()) return error_box(TR("Impossibile inizializzare il client HTTP")); unsigned long connection = client.QueryConnection("80", server); bool ok = connection != 0; if (ok) { ok = client.HttpGetDir(connection, remote_dir, list) != 0; client.RemoveConnection(connection); } return ok; } bool http_post(const char* server, const char* remote_file, const char* local_file, const char* authorization, byte*& answer, size_t& length) { TSocketClient client; if (!client.IsOk()) return error_box(TR("Impossibile inizializzare il client HTTP")); unsigned long connection = client.QueryConnection("80", server); bool ok = connection != 0; if (ok) { ok = client.HttpPostFile(connection, remote_file, local_file, authorization) != 0; client.RemoveConnection(connection); answer = client.GetBuffer(length); if (!ok) { error_box(FR("Impossibile spedire il file %s al server %s:\n%s"), local_file, server, answer); } } else return error_box(FR("Impossibile connettersi al server %s"), server); return ok; }