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