diff --git a/client/src/core/windows/pop.cc b/client/src/core/windows/pop.cc index c228e0e..23b94ce 100644 --- a/client/src/core/windows/pop.cc +++ b/client/src/core/windows/pop.cc @@ -44,11 +44,31 @@ namespace TN3270 { + class InvalidFormatException : public std::exception { + private: + string message; + + public: + InvalidFormatException(const IPC::Request::Type received, const IPC::Request::Type expected) { + + message = "Invalid format on IPC package, expecting \'"; + message += (char) expected; + message += "\' but received \'"; + message += (char) received; + message += "\'"; + + } + + const char * what() const noexcept override { + return message.c_str(); + } + }; + IPC::Request & IPC::Request::pop(std::string &value) { DataBlock * block = getNextBlock(); if(block->type != IPC::Request::String) - throw std::runtime_error("Invalid format"); + throw InvalidFormatException(block->type, IPC::Request::String); const char *ptr = (const char *) (block+1); @@ -80,7 +100,7 @@ break; default: - throw std::runtime_error("Invalid format"); + throw InvalidFormatException(block->type, IPC::Request::Int16); } return *this; @@ -107,7 +127,7 @@ break; default: - throw std::runtime_error("Invalid format"); + throw InvalidFormatException(block->type, IPC::Request::Uint16); } return *this; @@ -139,7 +159,7 @@ break; default: - throw std::runtime_error("Invalid format"); + throw InvalidFormatException(block->type, IPC::Request::Boolean); } return *this; diff --git a/client/src/core/windows/request.cc b/client/src/core/windows/request.cc index f805bea..d7184eb 100644 --- a/client/src/core/windows/request.cc +++ b/client/src/core/windows/request.cc @@ -37,6 +37,7 @@ */ #include + #include using std::string; @@ -46,6 +47,51 @@ #define PIPE_BUFFER_LENGTH 8192 +#ifdef DEBUG + + // From lib3270_trace_data + static void trace_data(const char *msg, const unsigned char *data, size_t datalen) +{ + // 00000000001111111111222222222233333333334444444444555555555566666666667777777777 + // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 + // xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx . . . . . . . . . . . . . . . . + + size_t ix; + char buffer[80]; + char hexvalue[3]; + + memset(buffer,0,sizeof(buffer)); + + std::cout << msg << "(" << datalen << " bytes)" << std::endl; + + for(ix = 0; ix < datalen; ix++) + { + size_t col = (ix%15); + + if(col == 0) + { + if(ix) { + std::cout << "\t" << buffer << std::endl; + } + + memset(buffer,' ',79); + buffer[79] = 0; + } + + snprintf(hexvalue,3,"%02x",data[ix]); + memcpy(buffer+(col*3),hexvalue,2); + + if(data[ix] > ' ') + buffer[48 + (col*2)] = data[ix]; + + } + + std::cout << "\t" << buffer << std::endl; + +} + +#endif // DEBUG + IPC::Request::Request(HANDLE hPipe, const char *name, uint16_t type) { this->hPipe = hPipe; @@ -114,7 +160,7 @@ IPC::Request & IPC::Request::call() { #ifdef DEBUG - // lib3270_trace_data(NULL,"Request block",(const char *) this->out.block, this->out.used); + // trace_data("Request block",(const unsigned char *) this->out.block, this->out.used); #endif // DEBUG debug("Sending request with ", *this->outvalues, " elements"); @@ -137,8 +183,19 @@ debug("Received response \"", in.block, "\" with ", in.used, " bytes"); + // + // Heaer format: + // + // STRING Response name + // uint16_t Return code + // uint16_t Arguments + // + // Data block: + // + // + #ifdef DEBUG - // lib3270_trace_data(NULL,"Response block",(const char *) this->in.block, this->in.used); + trace_data("Response block",(const unsigned char *) this->in.block, this->in.used); #endif // DEBUG // Extract response name diff --git a/client/src/include/lib3270/ipc/request.h b/client/src/include/lib3270/ipc/request.h index bca63b3..dcd3ac5 100644 --- a/client/src/include/lib3270/ipc/request.h +++ b/client/src/include/lib3270/ipc/request.h @@ -58,12 +58,8 @@ /// @brief PW3270 IPC Request/Response. class TN3270_PUBLIC Request { - private: - + public: #ifdef _WIN32 - /// @brief Pipe Handle. - HANDLE hPipe; - /// @brief IPC Data type. enum Type : uint8_t { String = 's', @@ -77,6 +73,13 @@ Int64 = 'x', Uint64 = 't' }; +#endif // _WIN32 + + private: + +#ifdef _WIN32 + /// @brief Pipe Handle. + HANDLE hPipe; struct { DWORD length; ///< @brief Length of input buffer. diff --git a/client/src/testprogram/testprogram.cc b/client/src/testprogram/testprogram.cc index 22c86ff..342adae 100644 --- a/client/src/testprogram/testprogram.cc +++ b/client/src/testprogram/testprogram.cc @@ -99,12 +99,19 @@ */ // Test Attributes - static void testAttributes(const char *session, const char *url) { + static void testAttributes(const char *session, const char *name) { TN3270::Host host{session}; + name="url"; + + cout << endl << endl; for(auto attribute : host.getAttributes()) { + if(name && *name && strcasecmp(name,"all") && strcasecmp(attribute.getName(),name)) { + continue; + } + cout << attribute.getName() << ":\t"; try { @@ -113,13 +120,17 @@ } catch(const std::exception &e) { - cout << e.what(); + cout << "Exception(" << e.what() << ")"; } cout << endl; + Sleep(100); + } + cout << endl << endl; + } // Performance test. @@ -237,17 +248,18 @@ #if ! defined(_MSC_VER) static struct option options[] = { - { "session", required_argument, 0, 's' }, - { "url", required_argument, 0, 'U' }, - { "perftest", no_argument, 0, 'P' }, - { "info", no_argument, 0, 'I' }, + { "session", required_argument, 0, 's' }, + { "url", required_argument, 0, 'U' }, + { "perftest", no_argument, 0, 'P' }, + { "attribute", optional_argument, 0, 'A' }, + { "info", no_argument, 0, 'I' }, { 0, 0, 0, 0} }; int long_index =0; int opt; - while((opt = getopt_long(argc, argv, "s:", options, &long_index )) != -1) { + while((opt = getopt_long(argc, argv, "s:A", options, &long_index )) != -1) { switch(opt) { case 's': @@ -255,6 +267,10 @@ cout << "Session: " << session << endl; break; + case 'A': + testAttributes(session,optarg); + break; + case 'U': url = optarg; cout << "URL: " << session << endl; diff --git a/server/src/core/getproperties.c b/server/src/core/getproperties.c index ca44154..5641f9f 100644 --- a/server/src/core/getproperties.c +++ b/server/src/core/getproperties.c @@ -127,6 +127,7 @@ GVariant * ipc3270_get_property(GObject *object, const gchar *property_name, GEr if(strprop[ix].get && !g_ascii_strcasecmp(strprop[ix].name, property_name)) { // Found it! + errno = 0; const char * value = strprop[ix].get(hSession); if(value) { @@ -134,9 +135,14 @@ GVariant * ipc3270_get_property(GObject *object, const gchar *property_name, GEr return g_variant_new_string(value); } - // Erro! - ipc3270_set_error(object,errno,error); - return NULL; + debug("%s=%s",property_name,"NULL"); + + if(errno) { + ipc3270_set_error(object,errno,error); + return NULL; + } + + return g_variant_new_string(""); } diff --git a/server/src/core/windows/inout.c b/server/src/core/windows/inout.c index 8576ad1..b8cfd9f 100644 --- a/server/src/core/windows/inout.c +++ b/server/src/core/windows/inout.c @@ -59,7 +59,7 @@ unsigned char * ipc3270_pack_error(const GError *error, size_t * szPacket) { txtptr += strlen((char *) txtptr) + 1; // Add RC - *((guint16 *) txtptr) = (guint16) error->code; + *((guint16 *) txtptr) = (guint16) (error->code ? error->code : -1); txtptr += sizeof(guint16); // Add message -- libgit2 0.21.2