Commit dcf0fc2cd7f4b1d0d22491a1b288bca594973ac7

Authored by Perry Werneck
1 parent 0d0564a2
Exists in master and in 1 other branch develop

Fixing IPC response on empty URL.

client/src/core/windows/pop.cc
@@ -44,11 +44,31 @@ @@ -44,11 +44,31 @@
44 44
45 namespace TN3270 { 45 namespace TN3270 {
46 46
  47 + class InvalidFormatException : public std::exception {
  48 + private:
  49 + string message;
  50 +
  51 + public:
  52 + InvalidFormatException(const IPC::Request::Type received, const IPC::Request::Type expected) {
  53 +
  54 + message = "Invalid format on IPC package, expecting \'";
  55 + message += (char) expected;
  56 + message += "\' but received \'";
  57 + message += (char) received;
  58 + message += "\'";
  59 +
  60 + }
  61 +
  62 + const char * what() const noexcept override {
  63 + return message.c_str();
  64 + }
  65 + };
  66 +
47 IPC::Request & IPC::Request::pop(std::string &value) { 67 IPC::Request & IPC::Request::pop(std::string &value) {
48 DataBlock * block = getNextBlock(); 68 DataBlock * block = getNextBlock();
49 69
50 if(block->type != IPC::Request::String) 70 if(block->type != IPC::Request::String)
51 - throw std::runtime_error("Invalid format"); 71 + throw InvalidFormatException(block->type, IPC::Request::String);
52 72
53 const char *ptr = (const char *) (block+1); 73 const char *ptr = (const char *) (block+1);
54 74
@@ -80,7 +100,7 @@ @@ -80,7 +100,7 @@
80 break; 100 break;
81 101
82 default: 102 default:
83 - throw std::runtime_error("Invalid format"); 103 + throw InvalidFormatException(block->type, IPC::Request::Int16);
84 } 104 }
85 105
86 return *this; 106 return *this;
@@ -107,7 +127,7 @@ @@ -107,7 +127,7 @@
107 break; 127 break;
108 128
109 default: 129 default:
110 - throw std::runtime_error("Invalid format"); 130 + throw InvalidFormatException(block->type, IPC::Request::Uint16);
111 } 131 }
112 132
113 return *this; 133 return *this;
@@ -139,7 +159,7 @@ @@ -139,7 +159,7 @@
139 break; 159 break;
140 160
141 default: 161 default:
142 - throw std::runtime_error("Invalid format"); 162 + throw InvalidFormatException(block->type, IPC::Request::Boolean);
143 } 163 }
144 164
145 return *this; 165 return *this;
client/src/core/windows/request.cc
@@ -37,6 +37,7 @@ @@ -37,6 +37,7 @@
37 */ 37 */
38 38
39 #include <ipc-client-internals.h> 39 #include <ipc-client-internals.h>
  40 + #include <lib3270/trace.h>
40 41
41 using std::string; 42 using std::string;
42 43
@@ -46,6 +47,51 @@ @@ -46,6 +47,51 @@
46 47
47 #define PIPE_BUFFER_LENGTH 8192 48 #define PIPE_BUFFER_LENGTH 8192
48 49
  50 +#ifdef DEBUG
  51 +
  52 + // From lib3270_trace_data
  53 + static void trace_data(const char *msg, const unsigned char *data, size_t datalen)
  54 +{
  55 + // 00000000001111111111222222222233333333334444444444555555555566666666667777777777
  56 + // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
  57 + // xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx . . . . . . . . . . . . . . . .
  58 +
  59 + size_t ix;
  60 + char buffer[80];
  61 + char hexvalue[3];
  62 +
  63 + memset(buffer,0,sizeof(buffer));
  64 +
  65 + std::cout << msg << "(" << datalen << " bytes)" << std::endl;
  66 +
  67 + for(ix = 0; ix < datalen; ix++)
  68 + {
  69 + size_t col = (ix%15);
  70 +
  71 + if(col == 0)
  72 + {
  73 + if(ix) {
  74 + std::cout << "\t" << buffer << std::endl;
  75 + }
  76 +
  77 + memset(buffer,' ',79);
  78 + buffer[79] = 0;
  79 + }
  80 +
  81 + snprintf(hexvalue,3,"%02x",data[ix]);
  82 + memcpy(buffer+(col*3),hexvalue,2);
  83 +
  84 + if(data[ix] > ' ')
  85 + buffer[48 + (col*2)] = data[ix];
  86 +
  87 + }
  88 +
  89 + std::cout << "\t" << buffer << std::endl;
  90 +
  91 +}
  92 +
  93 +#endif // DEBUG
  94 +
49 IPC::Request::Request(HANDLE hPipe, const char *name, uint16_t type) { 95 IPC::Request::Request(HANDLE hPipe, const char *name, uint16_t type) {
50 96
51 this->hPipe = hPipe; 97 this->hPipe = hPipe;
@@ -114,7 +160,7 @@ @@ -114,7 +160,7 @@
114 IPC::Request & IPC::Request::call() { 160 IPC::Request & IPC::Request::call() {
115 161
116 #ifdef DEBUG 162 #ifdef DEBUG
117 - // lib3270_trace_data(NULL,"Request block",(const char *) this->out.block, this->out.used); 163 + // trace_data("Request block",(const unsigned char *) this->out.block, this->out.used);
118 #endif // DEBUG 164 #endif // DEBUG
119 165
120 debug("Sending request with ", *this->outvalues, " elements"); 166 debug("Sending request with ", *this->outvalues, " elements");
@@ -137,8 +183,19 @@ @@ -137,8 +183,19 @@
137 183
138 debug("Received response \"", in.block, "\" with ", in.used, " bytes"); 184 debug("Received response \"", in.block, "\" with ", in.used, " bytes");
139 185
  186 + //
  187 + // Heaer format:
  188 + //
  189 + // STRING Response name
  190 + // uint16_t Return code
  191 + // uint16_t Arguments
  192 + //
  193 + // Data block:
  194 + //
  195 + //
  196 +
140 #ifdef DEBUG 197 #ifdef DEBUG
141 - // lib3270_trace_data(NULL,"Response block",(const char *) this->in.block, this->in.used); 198 + trace_data("Response block",(const unsigned char *) this->in.block, this->in.used);
142 #endif // DEBUG 199 #endif // DEBUG
143 200
144 // Extract response name 201 // Extract response name
client/src/include/lib3270/ipc/request.h
@@ -58,12 +58,8 @@ @@ -58,12 +58,8 @@
58 58
59 /// @brief PW3270 IPC Request/Response. 59 /// @brief PW3270 IPC Request/Response.
60 class TN3270_PUBLIC Request { 60 class TN3270_PUBLIC Request {
61 - private:  
62 - 61 + public:
63 #ifdef _WIN32 62 #ifdef _WIN32
64 - /// @brief Pipe Handle.  
65 - HANDLE hPipe;  
66 -  
67 /// @brief IPC Data type. 63 /// @brief IPC Data type.
68 enum Type : uint8_t { 64 enum Type : uint8_t {
69 String = 's', 65 String = 's',
@@ -77,6 +73,13 @@ @@ -77,6 +73,13 @@
77 Int64 = 'x', 73 Int64 = 'x',
78 Uint64 = 't' 74 Uint64 = 't'
79 }; 75 };
  76 +#endif // _WIN32
  77 +
  78 + private:
  79 +
  80 +#ifdef _WIN32
  81 + /// @brief Pipe Handle.
  82 + HANDLE hPipe;
80 83
81 struct { 84 struct {
82 DWORD length; ///< @brief Length of input buffer. 85 DWORD length; ///< @brief Length of input buffer.
client/src/testprogram/testprogram.cc
@@ -99,12 +99,19 @@ @@ -99,12 +99,19 @@
99 */ 99 */
100 100
101 // Test Attributes 101 // Test Attributes
102 - static void testAttributes(const char *session, const char *url) { 102 + static void testAttributes(const char *session, const char *name) {
103 103
104 TN3270::Host host{session}; 104 TN3270::Host host{session};
105 105
  106 + name="url";
  107 +
  108 + cout << endl << endl;
106 for(auto attribute : host.getAttributes()) { 109 for(auto attribute : host.getAttributes()) {
107 110
  111 + if(name && *name && strcasecmp(name,"all") && strcasecmp(attribute.getName(),name)) {
  112 + continue;
  113 + }
  114 +
108 cout << attribute.getName() << ":\t"; 115 cout << attribute.getName() << ":\t";
109 116
110 try { 117 try {
@@ -113,13 +120,17 @@ @@ -113,13 +120,17 @@
113 120
114 } catch(const std::exception &e) { 121 } catch(const std::exception &e) {
115 122
116 - cout << e.what(); 123 + cout << "Exception(" << e.what() << ")";
117 } 124 }
118 125
119 cout << endl; 126 cout << endl;
120 127
  128 + Sleep(100);
  129 +
121 } 130 }
122 131
  132 + cout << endl << endl;
  133 +
123 } 134 }
124 135
125 // Performance test. 136 // Performance test.
@@ -237,17 +248,18 @@ @@ -237,17 +248,18 @@
237 #if ! defined(_MSC_VER) 248 #if ! defined(_MSC_VER)
238 249
239 static struct option options[] = { 250 static struct option options[] = {
240 - { "session", required_argument, 0, 's' },  
241 - { "url", required_argument, 0, 'U' },  
242 - { "perftest", no_argument, 0, 'P' },  
243 - { "info", no_argument, 0, 'I' }, 251 + { "session", required_argument, 0, 's' },
  252 + { "url", required_argument, 0, 'U' },
  253 + { "perftest", no_argument, 0, 'P' },
  254 + { "attribute", optional_argument, 0, 'A' },
  255 + { "info", no_argument, 0, 'I' },
244 { 0, 0, 0, 0} 256 { 0, 0, 0, 0}
245 257
246 }; 258 };
247 259
248 int long_index =0; 260 int long_index =0;
249 int opt; 261 int opt;
250 - while((opt = getopt_long(argc, argv, "s:", options, &long_index )) != -1) { 262 + while((opt = getopt_long(argc, argv, "s:A", options, &long_index )) != -1) {
251 263
252 switch(opt) { 264 switch(opt) {
253 case 's': 265 case 's':
@@ -255,6 +267,10 @@ @@ -255,6 +267,10 @@
255 cout << "Session: " << session << endl; 267 cout << "Session: " << session << endl;
256 break; 268 break;
257 269
  270 + case 'A':
  271 + testAttributes(session,optarg);
  272 + break;
  273 +
258 case 'U': 274 case 'U':
259 url = optarg; 275 url = optarg;
260 cout << "URL: " << session << endl; 276 cout << "URL: " << session << endl;
server/src/core/getproperties.c
@@ -127,6 +127,7 @@ GVariant * ipc3270_get_property(GObject *object, const gchar *property_name, GEr @@ -127,6 +127,7 @@ GVariant * ipc3270_get_property(GObject *object, const gchar *property_name, GEr
127 if(strprop[ix].get && !g_ascii_strcasecmp(strprop[ix].name, property_name)) { 127 if(strprop[ix].get && !g_ascii_strcasecmp(strprop[ix].name, property_name)) {
128 128
129 // Found it! 129 // Found it!
  130 + errno = 0;
130 const char * value = strprop[ix].get(hSession); 131 const char * value = strprop[ix].get(hSession);
131 132
132 if(value) { 133 if(value) {
@@ -134,9 +135,14 @@ GVariant * ipc3270_get_property(GObject *object, const gchar *property_name, GEr @@ -134,9 +135,14 @@ GVariant * ipc3270_get_property(GObject *object, const gchar *property_name, GEr
134 return g_variant_new_string(value); 135 return g_variant_new_string(value);
135 } 136 }
136 137
137 - // Erro!  
138 - ipc3270_set_error(object,errno,error);  
139 - return NULL; 138 + debug("%s=%s",property_name,"NULL");
  139 +
  140 + if(errno) {
  141 + ipc3270_set_error(object,errno,error);
  142 + return NULL;
  143 + }
  144 +
  145 + return g_variant_new_string("");
140 146
141 } 147 }
142 148
server/src/core/windows/inout.c
@@ -59,7 +59,7 @@ unsigned char * ipc3270_pack_error(const GError *error, size_t * szPacket) { @@ -59,7 +59,7 @@ unsigned char * ipc3270_pack_error(const GError *error, size_t * szPacket) {
59 txtptr += strlen((char *) txtptr) + 1; 59 txtptr += strlen((char *) txtptr) + 1;
60 60
61 // Add RC 61 // Add RC
62 - *((guint16 *) txtptr) = (guint16) error->code; 62 + *((guint16 *) txtptr) = (guint16) (error->code ? error->code : -1);
63 txtptr += sizeof(guint16); 63 txtptr += sizeof(guint16);
64 64
65 // Add message 65 // Add message