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