refactoring of AgentConnection::getList
[public/netxms.git] / src / server / tools / nxget / nxget.cpp
1 /*
2 ** nxget - command line tool used to retrieve parameters from NetXMS agent
3 ** Copyright (C) 2004-2017 Victor Kirhenshtein
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 **
19 ** File: nxget.cpp
20 **
21 **/
22
23 #include <nms_common.h>
24 #include <nms_agent.h>
25 #include <nms_util.h>
26 #include <nxcpapi.h>
27 #include <nxsrvapi.h>
28
29 #ifndef _WIN32
30 #include <netdb.h>
31 #endif
32
33 #define MAX_LINE_SIZE 4096
34
35 /**
36 * Operations
37 */
38 enum Operation
39 {
40 CMD_GET = 0,
41 CMD_LIST = 1,
42 CMD_CHECK_SERVICE = 2,
43 CMD_GET_PARAMS = 3,
44 CMD_GET_CONFIG = 4,
45 CMD_TABLE = 5,
46 CMD_GET_SCREENSHOT = 6
47 };
48
49 /**
50 * Debug writer
51 */
52 static void DebugWriter(const TCHAR *tag, const TCHAR *text)
53 {
54 if (tag == NULL)
55 _tprintf(_T("%s\n"), text);
56 else
57 _tprintf(_T("<%s> %s\n"), tag, text);
58 }
59
60 /**
61 * Get single parameter
62 */
63 static int Get(AgentConnection *pConn, const TCHAR *pszParam, BOOL bShowName)
64 {
65 UINT32 dwError;
66 TCHAR szBuffer[1024];
67
68 dwError = pConn->getParameter(pszParam, 1024, szBuffer);
69 if (dwError == ERR_SUCCESS)
70 {
71 if (bShowName)
72 _tprintf(_T("%s = %s\n"), pszParam, szBuffer);
73 else
74 _tprintf(_T("%s\n"), szBuffer);
75 }
76 else
77 {
78 _tprintf(_T("%d: %s\n"), dwError, AgentErrorCodeToText(dwError));
79 }
80 fflush(stdout);
81 return (dwError == ERR_SUCCESS) ? 0 : 1;
82 }
83
84 /**
85 * Get list of values for enum parameters
86 */
87 static int List(AgentConnection *pConn, const TCHAR *pszParam)
88 {
89 StringList *data;
90 UINT32 rcc = pConn->getList(pszParam, &data);
91 if (rcc == ERR_SUCCESS)
92 {
93 for(int i = 0; i < data->size(); i++)
94 _tprintf(_T("%s\n"), data->get(i));
95 delete data;
96 }
97 else
98 {
99 _tprintf(_T("%d: %s\n"), rcc, AgentErrorCodeToText(rcc));
100 }
101 return (rcc == ERR_SUCCESS) ? 0 : 1;
102 }
103
104 /**
105 * Get table value
106 */
107 static int GetTable(AgentConnection *pConn, const TCHAR *pszParam)
108 {
109 Table *table;
110
111 UINT32 rcc = pConn->getTable(pszParam, &table);
112 if (rcc == ERR_SUCCESS)
113 {
114 // calculate column widths and print headers
115 int *widths = (int *)calloc(table->getNumColumns(), sizeof(int));
116 _puttc(_T('|'), stdout);
117 for(int c = 0; c < table->getNumColumns(); c++)
118 {
119 widths[c] = (int)_tcslen(table->getColumnName(c));
120 for(int i = 0; i < table->getNumRows(); i++)
121 {
122 int len = (int)_tcslen(table->getAsString(i, c));
123 if (len > widths[c])
124 widths[c] = len;
125 }
126 _tprintf(_T(" %*s |"), -widths[c], table->getColumnName(c));
127 }
128
129 _puttc(_T('\n'), stdout);
130 for(int i = 0; i < table->getNumRows(); i++)
131 {
132 _puttc(_T('|'), stdout);
133 for(int j = 0; j < table->getNumColumns(); j++)
134 {
135 _tprintf(_T(" %*s |"), -widths[j], table->getAsString(i, j));
136 }
137 _puttc(_T('\n'), stdout);
138 }
139 delete table;
140 free(widths);
141 }
142 else
143 {
144 _tprintf(_T("%u: %s\n"), rcc, AgentErrorCodeToText(rcc));
145 }
146 return (rcc == ERR_SUCCESS) ? 0 : 1;
147 }
148
149 /**
150 * Check network service state
151 */
152 static int CheckService(AgentConnection *pConn, int serviceType, UINT32 dwServiceAddr,
153 WORD wProto, WORD wPort, const TCHAR *pszRequest, const TCHAR *pszResponse)
154 {
155 UINT32 dwStatus, dwError;
156
157 dwError = pConn->checkNetworkService(&dwStatus, dwServiceAddr, serviceType, wPort,
158 wProto, pszRequest, pszResponse);
159 if (dwError == ERR_SUCCESS)
160 {
161 printf("Service status: %d\n", dwStatus);
162 }
163 else
164 {
165 _tprintf(_T("%d: %s\n"), dwError, AgentErrorCodeToText(dwError));
166 }
167 return (dwError == ERR_SUCCESS) ? 0 : 1;
168 }
169
170 /**
171 * List supported parameters
172 */
173 static int ListParameters(AgentConnection *pConn)
174 {
175 static const TCHAR *pszDataType[] = { _T("INT"), _T("UINT"), _T("INT64"), _T("UINT64"), _T("STRING"), _T("FLOAT"), _T("UNKNOWN") };
176
177 ObjectArray<AgentParameterDefinition> *paramList;
178 ObjectArray<AgentTableDefinition> *tableList;
179 UINT32 dwError = pConn->getSupportedParameters(&paramList, &tableList);
180 if (dwError == ERR_SUCCESS)
181 {
182 for(int i = 0; i < paramList->size(); i++)
183 {
184 AgentParameterDefinition *p = paramList->get(i);
185 _tprintf(_T("%s %s \"%s\"\n"), p->getName(),
186 pszDataType[(p->getDataType() < 6) && (p->getDataType() >= 0) ? p->getDataType() : 6],
187 p->getDescription());
188 }
189 delete paramList;
190 delete tableList;
191 }
192 else
193 {
194 _tprintf(_T("%d: %s\n"), dwError, AgentErrorCodeToText(dwError));
195 }
196 return (dwError == ERR_SUCCESS) ? 0 : 1;
197 }
198
199 /**
200 * Get configuration file
201 */
202 static int GetConfig(AgentConnection *pConn)
203 {
204 UINT32 dwError, dwSize;
205 TCHAR *pszFile;
206
207 dwError = pConn->getConfigFile(&pszFile, &dwSize);
208 if (dwError == ERR_SUCCESS)
209 {
210 TranslateStr(pszFile, _T("\r\n"), _T("\n"));
211 _fputts(pszFile, stdout);
212 if (dwSize > 0)
213 {
214 if (pszFile[dwSize - 1] != _T('\n'))
215 fputc('\n', stdout);
216 }
217 else
218 {
219 fputc('\n', stdout);
220 }
221 }
222 else
223 {
224 _tprintf(_T("%d: %s\n"), dwError, AgentErrorCodeToText(dwError));
225 }
226 return (dwError == ERR_SUCCESS) ? 0 : 1;
227 }
228
229 /**
230 * Get screenshot
231 */
232 static int GetScreenshot(AgentConnection *pConn, const char *sessionName, const char *fileName)
233 {
234 BYTE *data;
235 size_t size;
236 #ifdef UNICODE
237 WCHAR *wname = WideStringFromMBString(sessionName);
238 UINT32 dwError = pConn->takeScreenshot(wname, &data, &size);
239 free(wname);
240 #else
241 UINT32 dwError = pConn->takeScreenshot(sessionName, &data, &size);
242 #endif
243 if (dwError == ERR_SUCCESS)
244 {
245 FILE *f = fopen(fileName, "wb");
246 if (f != NULL)
247 {
248 if (data != NULL)
249 fwrite(data, 1, size, f);
250 fclose(f);
251 }
252 safe_free(data);
253 }
254 else
255 {
256 _tprintf(_T("%d: %s\n"), dwError, AgentErrorCodeToText(dwError));
257 }
258 return (dwError == ERR_SUCCESS) ? 0 : 1;
259 }
260
261 /**
262 * Startup
263 */
264 int main(int argc, char *argv[])
265 {
266 char *eptr;
267 BOOL start = TRUE, batchMode = FALSE, showNames = FALSE, useProxy = FALSE;
268 int i, ch, iPos, iExitCode = 3, iInterval = 0;
269 int authMethod = AUTH_NONE, proxyAuth = AUTH_NONE, serviceType = NETSRV_SSH;
270 #ifdef _WITH_ENCRYPTION
271 int iEncryptionPolicy = ENCRYPTION_ALLOWED;
272 #else
273 int iEncryptionPolicy = ENCRYPTION_DISABLED;
274 #endif
275 Operation operation = CMD_GET;
276 WORD agentPort = AGENT_LISTEN_PORT, proxyPort = AGENT_LISTEN_PORT;
277 WORD wServicePort = 0, wServiceProto = 0;
278 UINT32 dwTimeout = 5000, dwConnTimeout = 30000, dwServiceAddr = 0, dwError;
279 TCHAR szSecret[MAX_SECRET_LENGTH] = _T(""), szRequest[MAX_DB_STRING] = _T("");
280 TCHAR keyFile[MAX_PATH];
281 TCHAR szResponse[MAX_DB_STRING] = _T("");
282 char szProxy[MAX_OBJECT_NAME] = "";
283 TCHAR szProxySecret[MAX_SECRET_LENGTH] = _T("");
284 RSA *pServerKey = NULL;
285 #ifdef UNICODE
286 WCHAR *wcValue;
287 #endif
288
289 InitNetXMSProcess(true);
290 #ifdef _WIN32
291 SetExceptionHandler(SEHDefaultConsoleHandler, NULL, NULL, _T("nxget"), 0, FALSE, FALSE);
292 #endif
293 nxlog_set_debug_writer(DebugWriter);
294
295 GetNetXMSDirectory(nxDirData, keyFile);
296 _tcscat(keyFile, DFILE_KEYS);
297
298 // Parse command line
299 opterr = 1;
300 while((ch = getopt(argc, argv, "a:A:bCD:e:Ehi:IK:lno:O:p:P:r:R:s:S:t:Tvw:W:X:Z:")) != -1)
301 {
302 switch(ch)
303 {
304 case 'h': // Display help and exit
305 _tprintf(_T("Usage: nxget [<options>] <host> [<parameter> [<parameter> ...]]\n")
306 _T("Valid options are:\n")
307 _T(" -a auth : Authentication method. Valid methods are \"none\",\n")
308 _T(" \"plain\", \"md5\" and \"sha1\". Default is \"none\".\n")
309 _T(" -A auth : Authentication method for proxy agent.\n")
310 _T(" -b : Batch mode - get all parameters listed on command line.\n")
311 _T(" -C : Get agent's configuration file\n")
312 _T(" -D level : Set debug level (default is 0).\n")
313 #ifdef _WITH_ENCRYPTION
314 _T(" -e policy : Set encryption policy. Possible values are:\n")
315 _T(" 0 = Encryption disabled;\n")
316 _T(" 1 = Encrypt connection only if agent requires encryption;\n")
317 _T(" 2 = Encrypt connection if agent supports encryption;\n")
318 _T(" 3 = Force encrypted connection;\n")
319 _T(" Default value is 1.\n")
320 #endif
321 _T(" -E file : Take screenshot. First parameter is file name, second (optional) is session name.\n")
322 _T(" -h : Display help and exit.\n")
323 _T(" -i seconds : Get specified parameter(s) continously with given interval.\n")
324 _T(" -I : Get list of supported parameters.\n")
325 #ifdef _WITH_ENCRYPTION
326 _T(" -K file : Specify server's key file\n")
327 _T(" (default is %s).\n")
328 #endif
329 _T(" -l : Requested parameter is a list.\n")
330 _T(" -n : Show parameter's name in result.\n")
331 _T(" -o proto : Protocol number to be used for service check.\n")
332 _T(" -O port : Proxy agent's port number. Default is %d.\n")
333 _T(" -p port : Agent's port number. Default is %d.\n")
334 _T(" -P port : Network service port (to be used wth -S option).\n")
335 _T(" -r string : Service check request string.\n")
336 _T(" -R string : Service check expected response string.\n")
337 _T(" -s secret : Shared secret for authentication.\n")
338 _T(" -S addr : Check state of network service at given address.\n")
339 _T(" -t type : Set type of service to be checked.\n")
340 _T(" Possible types are: custom, ssh, pop3, smtp, ftp, http, https, telnet.\n")
341 _T(" -T : Requested parameter is a table.\n")
342 _T(" -v : Display version and exit.\n")
343 _T(" -w seconds : Set command timeout (default is 5 seconds).\n")
344 _T(" -W seconds : Set connection timeout (default is 30 seconds).\n")
345 _T(" -X addr : Use proxy agent at given address.\n")
346 _T(" -Z secret : Shared secret for proxy agent authentication.\n")
347 _T("\n"),
348 #ifdef _WITH_ENCRYPTION
349 keyFile,
350 #endif
351 agentPort, agentPort);
352 start = FALSE;
353 break;
354 case 'a': // Auth method
355 case 'A':
356 if (!strcmp(optarg, "none"))
357 i = AUTH_NONE;
358 else if (!strcmp(optarg, "plain"))
359 i = AUTH_PLAINTEXT;
360 else if (!strcmp(optarg, "md5"))
361 i = AUTH_MD5_HASH;
362 else if (!strcmp(optarg, "sha1"))
363 i = AUTH_SHA1_HASH;
364 else
365 {
366 printf("Invalid authentication method \"%s\"\n", optarg);
367 start = FALSE;
368 }
369 if (ch == 'a')
370 authMethod = i;
371 else
372 proxyAuth = i;
373 break;
374 case 'b': // Batch mode
375 batchMode = TRUE;
376 break;
377 case 'D': // debug level
378 nxlog_set_debug_level((int)strtol(optarg, NULL, 0));
379 break;
380 case 'i': // Interval
381 i = strtol(optarg, &eptr, 0);
382 if ((*eptr != 0) || (i <= 0))
383 {
384 printf("Invalid interval \"%s\"\n", optarg);
385 start = FALSE;
386 }
387 else
388 {
389 iInterval = i;
390 }
391 break;
392 case 'E':
393 operation = CMD_GET_SCREENSHOT;
394 break;
395 case 'I':
396 operation = CMD_GET_PARAMS;
397 break;
398 case 'C':
399 operation = CMD_GET_CONFIG;
400 break;
401 case 'l':
402 operation = CMD_LIST;
403 break;
404 case 'T':
405 operation = CMD_TABLE;
406 break;
407 case 'n': // Show names
408 showNames = TRUE;
409 break;
410 case 'p': // Agent's port number
411 case 'P': // Port number for service check
412 case 'O': // Proxy agent's port number
413 i = strtol(optarg, &eptr, 0);
414 if ((*eptr != 0) || (i < 0) || (i > 65535))
415 {
416 printf("Invalid port number \"%s\"\n", optarg);
417 start = FALSE;
418 }
419 else
420 {
421 if (ch == 'p')
422 agentPort = (WORD)i;
423 else if (ch == 'O')
424 proxyPort = (WORD)i;
425 else
426 wServicePort = (WORD)i;
427 }
428 break;
429 case 'r': // Service check request string
430 #ifdef UNICODE
431 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, optarg, -1, szRequest, MAX_DB_STRING);
432 szRequest[MAX_DB_STRING - 1] = 0;
433 #else
434 nx_strncpy(szRequest, optarg, MAX_DB_STRING);
435 #endif
436 break;
437 case 'R': // Service check response string
438 #ifdef UNICODE
439 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, optarg, -1, szResponse, MAX_DB_STRING);
440 szResponse[MAX_DB_STRING - 1] = 0;
441 #else
442 nx_strncpy(szResponse, optarg, MAX_DB_STRING);
443 #endif
444 break;
445 case 's': // Shared secret
446 #ifdef UNICODE
447 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, optarg, -1, szSecret, MAX_SECRET_LENGTH);
448 szSecret[MAX_SECRET_LENGTH - 1] = 0;
449 #else
450 nx_strncpy(szSecret, optarg, MAX_SECRET_LENGTH);
451 #endif
452 break;
453 case 'S': // Check service
454 operation = CMD_CHECK_SERVICE;
455 dwServiceAddr = ntohl(inet_addr(optarg));
456 if ((dwServiceAddr == INADDR_NONE) || (dwServiceAddr == INADDR_ANY))
457 {
458 _tprintf(_T("Invalid IP address \"%hs\"\n"), optarg);
459 start = FALSE;
460 }
461 break;
462 case 't': // Service type
463 serviceType = strtol(optarg, &eptr, 0);
464 if (*eptr != 0)
465 {
466 if (!stricmp(optarg, "custom"))
467 {
468 serviceType = NETSRV_CUSTOM;
469 }
470 else if (!stricmp(optarg, "ftp"))
471 {
472 serviceType = NETSRV_FTP;
473 }
474 else if (!stricmp(optarg, "http"))
475 {
476 serviceType = NETSRV_HTTP;
477 }
478 else if (!stricmp(optarg, "https"))
479 {
480 serviceType = NETSRV_HTTPS;
481 }
482 else if (!stricmp(optarg, "pop3"))
483 {
484 serviceType = NETSRV_POP3;
485 }
486 else if (!stricmp(optarg, "smtp"))
487 {
488 serviceType = NETSRV_SMTP;
489 }
490 else if (!stricmp(optarg, "ssh"))
491 {
492 serviceType = NETSRV_SSH;
493 }
494 else if (!stricmp(optarg, "telnet"))
495 {
496 serviceType = NETSRV_TELNET;
497 }
498 else
499 {
500 _tprintf(_T("Invalid service type \"%hs\"\n"), optarg);
501 start = FALSE;
502 }
503 }
504 break;
505 case 'o': // Protocol number for service check
506 i = strtol(optarg, &eptr, 0);
507 if ((*eptr != 0) || (i < 0) || (i > 65535))
508 {
509 _tprintf(_T("Invalid protocol number \"%hs\"\n"), optarg);
510 start = FALSE;
511 }
512 else
513 {
514 wServiceProto = (WORD)i;
515 }
516 break;
517 case 'v': // Print version and exit
518 _tprintf(_T("NetXMS GET command-line utility Version ") NETXMS_VERSION_STRING _T("\n"));
519 start = FALSE;
520 break;
521 case 'w': // Command timeout
522 i = strtol(optarg, &eptr, 0);
523 if ((*eptr != 0) || (i < 1) || (i > 120))
524 {
525 _tprintf(_T("Invalid timeout \"%hs\"\n"), optarg);
526 start = FALSE;
527 }
528 else
529 {
530 dwTimeout = (UINT32)i * 1000; // Convert to milliseconds
531 }
532 break;
533 case 'W': // Connection timeout
534 i = strtol(optarg, &eptr, 0);
535 if ((*eptr != 0) || (i < 1) || (i > 120))
536 {
537 printf("Invalid timeout \"%s\"\n", optarg);
538 start = FALSE;
539 }
540 else
541 {
542 dwConnTimeout = (UINT32)i * 1000; // Convert to milliseconds
543 }
544 break;
545 #ifdef _WITH_ENCRYPTION
546 case 'e':
547 iEncryptionPolicy = atoi(optarg);
548 if ((iEncryptionPolicy < 0) ||
549 (iEncryptionPolicy > 3))
550 {
551 printf("Invalid encryption policy %d\n", iEncryptionPolicy);
552 start = FALSE;
553 }
554 break;
555 case 'K':
556 #ifdef UNICODE
557 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, optarg, -1, keyFile, MAX_PATH);
558 keyFile[MAX_PATH - 1] = 0;
559 #else
560 nx_strncpy(keyFile, optarg, MAX_PATH);
561 #endif
562 break;
563 #else
564 case 'e':
565 case 'K':
566 printf("ERROR: This tool was compiled without encryption support\n");
567 start = FALSE;
568 break;
569 #endif
570 case 'X': // Use proxy
571 strncpy(szProxy, optarg, MAX_OBJECT_NAME);
572 szProxy[MAX_OBJECT_NAME - 1] = 0;
573 useProxy = TRUE;
574 break;
575 case 'Z': // Shared secret for proxy agent
576 #ifdef UNICODE
577 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, optarg, -1, szProxySecret, MAX_SECRET_LENGTH);
578 szProxySecret[MAX_SECRET_LENGTH - 1] = 0;
579 #else
580 nx_strncpy(szProxySecret, optarg, MAX_SECRET_LENGTH);
581 #endif
582 break;
583 case '?':
584 start = FALSE;
585 break;
586 default:
587 break;
588 }
589 }
590
591 // Check parameter correctness
592 if (start)
593 {
594 if (argc - optind < (((operation == CMD_CHECK_SERVICE) || (operation == CMD_GET_PARAMS) || (operation == CMD_GET_CONFIG)) ? 1 : 2))
595 {
596 printf("Required argument(s) missing.\nUse nxget -h to get complete command line syntax.\n");
597 start = FALSE;
598 }
599 else if ((authMethod != AUTH_NONE) && (szSecret[0] == 0))
600 {
601 printf("Shared secret not specified or empty\n");
602 start = FALSE;
603 }
604
605 // Load server key if requested
606 #ifdef _WITH_ENCRYPTION
607 if ((iEncryptionPolicy != ENCRYPTION_DISABLED) && start)
608 {
609 if (InitCryptoLib(0xFFFF))
610 {
611 pServerKey = LoadRSAKeys(keyFile);
612 if (pServerKey == NULL)
613 {
614 _tprintf(_T("Error loading RSA keys from \"%s\"\n"), keyFile);
615 if (iEncryptionPolicy == ENCRYPTION_REQUIRED)
616 start = FALSE;
617 }
618 }
619 else
620 {
621 printf("Error initializing cryptografy module\n");
622 if (iEncryptionPolicy == ENCRYPTION_REQUIRED)
623 start = FALSE;
624 }
625 }
626 #endif
627
628 // If everything is ok, start communications
629 if (start)
630 {
631 // Initialize WinSock
632 #ifdef _WIN32
633 WSADATA wsaData;
634 WSAStartup(2, &wsaData);
635 #endif
636 InetAddress addr = InetAddress::resolveHostName(argv[optind]);
637 InetAddress proxyAddr = useProxy ? InetAddress::resolveHostName(szProxy) : InetAddress();
638 if (!addr.isValid())
639 {
640 fprintf(stderr, "Invalid host name or address \"%s\"\n", argv[optind]);
641 }
642 else if (useProxy && !proxyAddr.isValid())
643 {
644 fprintf(stderr, "Invalid host name or address \"%s\"\n", szProxy);
645 }
646 else
647 {
648 AgentConnection *conn = new AgentConnection(addr, agentPort, authMethod, szSecret);
649
650 conn->setConnectionTimeout(dwConnTimeout);
651 conn->setCommandTimeout(dwTimeout);
652 conn->setEncryptionPolicy(iEncryptionPolicy);
653 if (useProxy)
654 conn->setProxy(proxyAddr, proxyPort, proxyAuth, szProxySecret);
655 if (conn->connect(pServerKey, &dwError))
656 {
657 do
658 {
659 switch(operation)
660 {
661 case CMD_GET:
662 iPos = optind + 1;
663 do
664 {
665 #ifdef UNICODE
666 wcValue = WideStringFromMBString(argv[iPos++]);
667 iExitCode = Get(conn, wcValue, showNames);
668 free(wcValue);
669 #else
670 iExitCode = Get(conn, argv[iPos++], showNames);
671 #endif
672 } while((iExitCode == 0) && (batchMode) && (iPos < argc));
673 break;
674 case CMD_LIST:
675 #ifdef UNICODE
676 wcValue = WideStringFromMBString(argv[optind + 1]);
677 iExitCode = List(conn, wcValue);
678 free(wcValue);
679 #else
680 iExitCode = List(conn, argv[optind + 1]);
681 #endif
682 break;
683 case CMD_TABLE:
684 #ifdef UNICODE
685 wcValue = WideStringFromMBString(argv[optind + 1]);
686 iExitCode = GetTable(conn, wcValue);
687 free(wcValue);
688 #else
689 iExitCode = GetTable(conn, argv[optind + 1]);
690 #endif
691 break;
692 case CMD_CHECK_SERVICE:
693 iExitCode = CheckService(conn, serviceType, dwServiceAddr,
694 wServiceProto, wServicePort, szRequest, szResponse);
695 break;
696 case CMD_GET_PARAMS:
697 iExitCode = ListParameters(conn);
698 break;
699 case CMD_GET_CONFIG:
700 iExitCode = GetConfig(conn);
701 break;
702 case CMD_GET_SCREENSHOT:
703 iExitCode = GetScreenshot(conn, (argc > optind + 2) ? argv[optind + 2] : "Console", argv[optind + 1]);
704 break;
705 default:
706 break;
707 }
708 ThreadSleep(iInterval);
709 }
710 while(iInterval > 0);
711 }
712 else
713 {
714 _tprintf(_T("%d: %s\n"), dwError, AgentErrorCodeToText(dwError));
715 iExitCode = 2;
716 }
717 conn->decRefCount();
718 }
719 }
720 }
721
722 MsgWaitQueue::shutdown();
723 return iExitCode;
724 }