Fixed bug in StartupDelay handling
[public/netxms.git] / src / agent / core / nxagentd.cpp
CommitLineData
e7474978
VK
1/*
2** NetXMS multiplatform core agent
3** Copyright (C) 2003, 2004 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 usefu,,
11** but ITHOUT 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** $module: nxagentd.cpp
20**
21**/
22
23#include "nxagentd.h"
24
b492a277 25#if defined(_WIN32)
e9580fef 26#include <conio.h>
b492a277 27#elif defined(_NETWARE)
ead6cccb 28#include <screen.h>
b492a277
VK
29#else
30#include <signal.h>
ead6cccb
VK
31#endif
32
e9580fef
VK
33
34//
35// Externals
36//
37
ccdbbb52 38THREAD_RESULT THREAD_CALL ListenerThread(void *);
e9580fef 39
e7474978
VK
40
41//
42// Valid options for getopt()
43//
44
3b1f0a0a 45#if defined(_WIN32)
1980ebfc 46#define VALID_OPTIONS "c:CdDEhIRsSUv"
3b1f0a0a
VK
47#elif defined(_NETWARE)
48#define VALID_OPTIONS "c:CDhv"
e7474978 49#else
6f4bc3b9 50#define VALID_OPTIONS "c:CdDhp:v"
e7474978
VK
51#endif
52
53
54//
55// Actions
56//
57
1980ebfc
VK
58#define ACTION_NONE 0
59#define ACTION_RUN_AGENT 1
60#define ACTION_INSTALL_SERVICE 2
61#define ACTION_REMOVE_SERVICE 3
62#define ACTION_START_SERVICE 4
63#define ACTION_STOP_SERVICE 5
64#define ACTION_CHECK_CONFIG 6
65#define ACTION_INSTALL_EVENT_SOURCE 7
66#define ACTION_REMOVE_EVENT_SOURCE 8
e7474978
VK
67
68
69//
70// Global variables
71//
72
73DWORD g_dwFlags = 0;
74char g_szLogFile[MAX_PATH] = AGENT_DEFAULT_LOG;
75char g_szSharedSecret[MAX_SECRET_LENGTH] = "admin";
ae9cddaf 76char g_szConfigFile[MAX_PATH] = AGENT_DEFAULT_CONFIG;
d096bcdd 77char g_szFileStore[MAX_PATH] = AGENT_DEFAULT_FILE_STORE;
9383147c 78char g_szPlatformSuffix[MAX_PSUFFIX_LENGTH] = "";
e7474978 79WORD g_wListenPort = AGENT_LISTEN_PORT;
d096bcdd 80SERVER_INFO g_pServerList[MAX_SERVERS];
e7474978
VK
81DWORD g_dwServerCount = 0;
82DWORD g_dwTimeOut = 5000; // Request timeout in milliseconds
83time_t g_dwAgentStartTime;
d231de5d 84DWORD g_dwStartupDelay = 0;
e7474978 85
6f4bc3b9
VK
86#if !defined(_WIN32) && !defined(_NETWARE)
87char g_szPidFile[MAX_PATH] = "/var/run/nxagentd.pid";
88#endif
89
dc0e93b4
VK
90#ifdef _WIN32
91DWORD (__stdcall *imp_GetGuiResources)(HANDLE, DWORD);
92BOOL (__stdcall *imp_GetProcessIoCounters)(HANDLE, PIO_COUNTERS);
93BOOL (__stdcall *imp_GetPerformanceInfo)(PPERFORMANCE_INFORMATION, DWORD);
94BOOL (__stdcall *imp_GlobalMemoryStatusEx)(LPMEMORYSTATUSEX);
6849d9be 95DWORD (__stdcall *imp_HrLanConnectionNameFromGuidOrPath)(LPWSTR, LPWSTR, LPWSTR, LPDWORD);
dc0e93b4
VK
96#endif /* _WIN32 */
97
e7474978
VK
98
99//
100// Static variables
101//
102
8655c391
VK
103static char *m_pszActionList = NULL;
104static char *m_pszServerList = NULL;
d096bcdd 105static char *m_pszInstallServerList = NULL;
8655c391
VK
106static char *m_pszSubagentList = NULL;
107static char *m_pszExtParamList = NULL;
449e3da9 108static CONDITION m_hCondShutdown = INVALID_CONDITION_HANDLE;
e7474978
VK
109
110
111//
112// Configuration file template
113//
114
115static NX_CFG_TEMPLATE cfgTemplate[] =
116{
8655c391 117 { "Action", CT_STRING_LIST, '\n', 0, 0, 0, &m_pszActionList },
3c774461 118 { "EnableActions", CT_BOOLEAN, 0, 0, AF_ENABLE_ACTIONS, 0, &g_dwFlags },
8655c391 119 { "ExternalParameter", CT_STRING_LIST, '\n', 0, 0, 0, &m_pszExtParamList },
d096bcdd
VK
120 { "FileStore", CT_STRING, 0, 0, MAX_PATH, 0, g_szFileStore },
121 { "InstallationServers", CT_STRING_LIST, ',', 0, 0, 0, &m_pszInstallServerList },
e7474978
VK
122 { "ListenPort", CT_WORD, 0, 0, 0, 0, &g_wListenPort },
123 { "LogFile", CT_STRING, 0, 0, MAX_PATH, 0, g_szLogFile },
dc0e93b4 124 { "LogUnresolvedSymbols", CT_BOOLEAN, 0, 0, AF_LOG_UNRESOLVED_SYMBOLS, 0, &g_dwFlags },
9383147c 125 { "PlatformSuffix", CT_STRING, 0, 0, MAX_PSUFFIX_LENGTH, 0, g_szPlatformSuffix },
e7474978 126 { "RequireAuthentication", CT_BOOLEAN, 0, 0, AF_REQUIRE_AUTH, 0, &g_dwFlags },
8655c391 127 { "Servers", CT_STRING_LIST, ',', 0, 0, 0, &m_pszServerList },
e9580fef 128 { "SharedSecret", CT_STRING, 0, 0, MAX_SECRET_LENGTH, 0, g_szSharedSecret },
d231de5d 129 { "StartupDelay", CT_LONG, 0, 0, 0, 0, &g_dwStartupDelay },
8655c391 130 { "SubAgent", CT_STRING_LIST, '\n', 0, 0, 0, &m_pszSubagentList },
e7474978
VK
131 { "Timeout", CT_LONG, 0, 0, 0, 0, &g_dwTimeOut },
132 { "", CT_END_OF_LIST, 0, 0, 0, 0, NULL }
133};
134
135
136//
137// Help text
138//
139
140static char m_szHelpText[] =
141 "Usage: nxagentd [options]\n"
142 "Where valid options are:\n"
143 " -c <file> : Use configuration file <file> (default " AGENT_DEFAULT_CONFIG ")\n"
144 " -C : Check configuration file and exit\n"
3b1f0a0a 145#ifndef _NETWARE
e7474978 146 " -d : Run as daemon/service\n"
3b1f0a0a 147#endif
7c205c0c 148 " -D : Turn on debug output\n"
e7474978
VK
149 " -h : Display help and exit\n"
150#ifdef _WIN32
151 " -I : Install Windows service\n"
152 " -R : Remove Windows service\n"
153 " -s : Start Windows servive\n"
154 " -S : Stop Windows service\n"
155#endif
156 " -v : Display version and exit\n"
157 "\n";
158
159
dc0e93b4
VK
160#ifdef _WIN32
161
162//
163// Get proc address and write log file
164//
165
166static FARPROC GetProcAddressAndLog(HMODULE hModule, LPCSTR procName)
167{
168 FARPROC ptr;
169
170 ptr = GetProcAddress(hModule, procName);
171 if ((ptr == NULL) && (g_dwFlags & AF_LOG_UNRESOLVED_SYMBOLS))
172 WriteLog(MSG_NO_FUNCTION, EVENTLOG_WARNING_TYPE, "s", procName);
173 return ptr;
174}
175
176
177//
178// Import symbols
179//
180
181static void ImportSymbols(void)
182{
183 HMODULE hModule;
184
6849d9be 185 // USER32.DLL
dc0e93b4
VK
186 hModule = GetModuleHandle("USER32.DLL");
187 if (hModule != NULL)
188 {
189 imp_GetGuiResources = (DWORD (__stdcall *)(HANDLE, DWORD))GetProcAddressAndLog(hModule,"GetGuiResources");
190 }
191 else
192 {
193 WriteLog(MSG_NO_DLL, EVENTLOG_WARNING_TYPE, "s", "USER32.DLL");
194 }
195
6849d9be 196 // KERNEL32.DLL
dc0e93b4
VK
197 hModule = GetModuleHandle("KERNEL32.DLL");
198 if (hModule != NULL)
199 {
200 imp_GetProcessIoCounters = (BOOL (__stdcall *)(HANDLE, PIO_COUNTERS))GetProcAddressAndLog(hModule,"GetProcessIoCounters");
201 imp_GlobalMemoryStatusEx = (BOOL (__stdcall *)(LPMEMORYSTATUSEX))GetProcAddressAndLog(hModule,"GlobalMemoryStatusEx");
202 }
203 else
204 {
205 WriteLog(MSG_NO_DLL, EVENTLOG_WARNING_TYPE, "s", "KERNEL32.DLL");
206 }
207
6849d9be 208 // PSAPI.DLL
dc0e93b4
VK
209 hModule = GetModuleHandle("PSAPI.DLL");
210 if (hModule != NULL)
211 {
212 imp_GetPerformanceInfo = (BOOL (__stdcall *)(PPERFORMANCE_INFORMATION, DWORD))GetProcAddressAndLog(hModule,"GetPerformanceInfo");
213 }
214 else
215 {
216 WriteLog(MSG_NO_DLL, EVENTLOG_WARNING_TYPE, "s", "PSAPI.DLL");
217 }
6849d9be
VK
218
219 // NETMAN.DLL
220 hModule = LoadLibrary("NETMAN.DLL");
221 if (hModule != NULL)
222 {
223 imp_HrLanConnectionNameFromGuidOrPath =
224 (DWORD (__stdcall *)(LPWSTR, LPWSTR, LPWSTR, LPDWORD))GetProcAddressAndLog(hModule,
225 "HrLanConnectionNameFromGuidOrPath");
226 }
227 else
228 {
229 WriteLog(MSG_NO_DLL, EVENTLOG_WARNING_TYPE, "s", "NETMAN.DLL");
230 }
dc0e93b4
VK
231}
232
233#endif /* _WIN32 */
234
235
ae9cddaf
VK
236//
237// This function writes message from subagent to agent's log
238//
239
240static void WriteSubAgentMsg(int iLevel, TCHAR *pszMsg)
241{
242 WriteLog(MSG_SUBAGENT_MSG, iLevel, "s", pszMsg);
243}
244
245
b492a277
VK
246//
247// Signal handler for UNIX platforms
248//
249
250#ifndef _WIN32
251
252void OnSignal(int iSignal)
253{
254 WriteLog(MSG_SIGNAL_RECEIVED, EVENTLOG_WARNING_TYPE, "d", iSignal);
255 switch(iSignal)
256 {
257 case SIGTERM:
258 case SIGINT:
259 ConditionSet(m_hCondShutdown);
260 break;
261 case SIGSEGV:
6120112b 262 abort();
b492a277
VK
263 exit(5);
264 break;
265 default:
266 break;
267 }
268}
269
270#endif
271
272
273
e7474978
VK
274//
275// Initialization routine
276//
277
278BOOL Initialize(void)
279{
e9580fef
VK
280 char *pItem, *pEnd;
281
e7474978
VK
282 // Open log file
283 InitLog();
284
e9580fef
VK
285#ifdef _WIN32
286 WSADATA wsaData;
287 if (WSAStartup(2, &wsaData) != 0)
288 {
289 WriteLog(MSG_WSASTARTUP_FAILED, EVENTLOG_ERROR_TYPE, "e", WSAGetLastError());
290 return FALSE;
291 }
292#endif
293
ae9cddaf
VK
294 // Initialize logger for subagents
295 InitSubAgentsLogger(WriteSubAgentMsg);
296
e9580fef
VK
297 // Initialize built-in parameters
298 if (!InitParameterList())
299 return FALSE;
300
dc0e93b4
VK
301#ifdef _WIN32
302 // Dynamically import functions that may not be presented in all Windows versions
303 ImportSymbols();
304#endif
305
e9580fef 306 // Parse server list
8655c391 307 if (m_pszServerList != NULL)
e9580fef 308 {
8655c391 309 for(pItem = m_pszServerList; *pItem != 0; pItem = pEnd + 1)
e9580fef 310 {
8655c391
VK
311 pEnd = strchr(pItem, ',');
312 if (pEnd != NULL)
313 *pEnd = 0;
314 StrStrip(pItem);
d096bcdd
VK
315 g_pServerList[g_dwServerCount].dwIpAddr = inet_addr(pItem);
316 if ((g_pServerList[g_dwServerCount].dwIpAddr == INADDR_NONE) ||
317 (g_pServerList[g_dwServerCount].dwIpAddr == INADDR_ANY))
8655c391
VK
318 {
319 if (!(g_dwFlags & AF_DAEMON))
320 printf("Invalid server address '%s'\n", pItem);
321 }
322 else
323 {
d096bcdd 324 g_pServerList[g_dwServerCount].bInstallationServer = FALSE;
8655c391
VK
325 g_dwServerCount++;
326 }
e9580fef 327 }
8655c391 328 free(m_pszServerList);
e9580fef
VK
329 }
330
d096bcdd
VK
331 // Parse installation server list
332 if (m_pszInstallServerList != NULL)
333 {
334 DWORD i, dwAddr;
335
336 for(pItem = m_pszInstallServerList; *pItem != 0; pItem = pEnd + 1)
337 {
338 pEnd = strchr(pItem, ',');
339 if (pEnd != NULL)
340 *pEnd = 0;
341 StrStrip(pItem);
342
343 dwAddr = inet_addr(pItem);
344 if ((dwAddr == INADDR_NONE) ||
345 (dwAddr == INADDR_ANY))
346 {
347 if (!(g_dwFlags & AF_DAEMON))
348 printf("Invalid server address '%s'\n", pItem);
349 }
350 else
351 {
352 for(i = 0; i < g_dwServerCount; i++)
353 if (g_pServerList[i].dwIpAddr == dwAddr)
354 break;
355
356 if (i == g_dwServerCount)
357 {
358 g_pServerList[g_dwServerCount].dwIpAddr = dwAddr;
359 g_pServerList[g_dwServerCount].bInstallationServer = TRUE;
360 g_dwServerCount++;
361 }
362 else
363 {
364 g_pServerList[i].bInstallationServer = TRUE;
365 }
366 }
367 }
368 free(m_pszInstallServerList);
369 }
370
e9580fef 371 // Load subagents
8655c391 372 if (m_pszSubagentList != NULL)
e9580fef 373 {
8655c391
VK
374 for(pItem = m_pszSubagentList; *pItem != 0; pItem = pEnd + 1)
375 {
376 pEnd = strchr(pItem, '\n');
377 if (pEnd != NULL)
378 *pEnd = 0;
379 StrStrip(pItem);
380 LoadSubAgent(pItem);
381 }
382 free(m_pszSubagentList);
e9580fef
VK
383 }
384
3c774461 385 // Parse action list
8655c391 386 if (m_pszActionList != NULL)
3c774461 387 {
8655c391
VK
388 for(pItem = m_pszActionList; *pItem != 0; pItem = pEnd + 1)
389 {
390 pEnd = strchr(pItem, '\n');
391 if (pEnd != NULL)
392 *pEnd = 0;
393 StrStrip(pItem);
394 if (!AddActionFromConfig(pItem))
395 WriteLog(MSG_ADD_ACTION_FAILED, EVENTLOG_WARNING_TYPE, "s", pItem);
396 }
397 free(m_pszActionList);
3c774461
VK
398 }
399
21a2454a
VK
400 // Parse external parameters list
401 if (m_pszExtParamList != NULL)
402 {
403 for(pItem = m_pszExtParamList; *pItem != 0; pItem = pEnd + 1)
404 {
405 pEnd = strchr(pItem, '\n');
406 if (pEnd != NULL)
407 *pEnd = 0;
408 StrStrip(pItem);
409 if (!AddExternalParameter(pItem))
410 WriteLog(MSG_ADD_EXT_PARAM_FAILED, EVENTLOG_WARNING_TYPE, "s", pItem);
411 }
412 free(m_pszExtParamList);
413 }
414
d231de5d
VK
415 ThreadSleep(1);
416
417 // If StartupDelay is greater than zero, then wait
418 if (g_dwStartupDelay > 0)
419 {
420 if (g_dwFlags & AF_DAEMON)
421 {
422 ThreadSleep(g_dwStartupDelay);
423 }
424 else
425 {
426 DWORD i;
427
428 printf("XXXXXX%*s]\rWAIT [", g_dwStartupDelay, " ");
429 fflush(stdout);
430 for(i = 0; i < g_dwStartupDelay; i++)
431 {
432 ThreadSleep(1);
433 putc('.', stdout);
434 fflush(stdout);
435 }
436 printf("\n");
437 }
438 }
439
e7474978
VK
440 // Agent start time
441 g_dwAgentStartTime = time(NULL);
442
e9580fef
VK
443 // Start network listener
444 ThreadCreate(ListenerThread, 0, NULL);
445
446 m_hCondShutdown = ConditionCreate(FALSE);
7c205c0c 447 ThreadSleep(1);
e9580fef 448
e7474978
VK
449 return TRUE;
450}
451
452
453//
454// Shutdown routine
455//
456
457void Shutdown(void)
458{
e9580fef
VK
459 // Set shutdowm flag and sleep for some time
460 // to allow other threads to finish
461 g_dwFlags |= AF_SHUTDOWN;
462 ThreadSleep(5);
463
47e0446b 464 UnloadAllSubAgents();
e7474978 465 CloseLog();
e9580fef
VK
466
467 // Notify main thread about shutdown
468 ConditionSet(m_hCondShutdown);
6f4bc3b9
VK
469
470 // Remove PID file
471#if !defined(_WIN32) && !defined(_NETWARE)
472 remove(g_szPidFile);
473#endif
e7474978
VK
474}
475
476
477//
478// Common Main()
479//
480
481void Main(void)
482{
483 WriteLog(MSG_AGENT_STARTED, EVENTLOG_INFORMATION_TYPE, NULL);
e9580fef
VK
484
485 if (g_dwFlags & AF_DAEMON)
486 {
487 ConditionWait(m_hCondShutdown, INFINITE);
488 }
489 else
490 {
3b1f0a0a 491#if defined(_WIN32)
e9580fef
VK
492 printf("Agent running. Press ESC to shutdown.\n");
493 while(1)
494 {
495 if (getch() == 27)
496 break;
497 }
498 printf("Agent shutting down...\n");
499 Shutdown();
3b1f0a0a
VK
500#elif defined(_NETWARE)
501 printf("Agent running. Type UNLOAD NXAGENTD on the system console for shutdown.\n");
502 ConditionWait(m_hCondShutdown, INFINITE);
e9580fef
VK
503#else
504 printf("Agent running. Press Ctrl+C to shutdown.\n");
505 ConditionWait(m_hCondShutdown, INFINITE);
506#endif
507 }
e7474978
VK
508}
509
510
511//
512// Startup
513//
514
515int main(int argc, char *argv[])
516{
517 int ch, iExitCode = 0, iAction = ACTION_RUN_AGENT;
af4a704a
VK
518#ifdef _WIN32
519 char szModuleName[MAX_PATH];
520#endif
e7474978 521
ead6cccb
VK
522#ifdef _NETWARE
523 setscreenmode(SCR_AUTOCLOSE_ON_EXIT | SCR_COLOR_ATTRS);
524#endif
525
e7474978
VK
526 // Parse command line
527 opterr = 1;
528 while((ch = getopt(argc, argv, VALID_OPTIONS)) != -1)
529 {
530 switch(ch)
531 {
532 case 'h': // Display help and exit
533 printf(m_szHelpText);
534 iAction = ACTION_NONE;
535 break;
536 case 'd': // Run as daemon
537 g_dwFlags |= AF_DAEMON;
538 break;
539 case 'D': // Turn on debug output
540 g_dwFlags |= AF_DEBUG;
541 break;
542 case 'c': // Configuration file
ae9cddaf 543 strncpy(g_szConfigFile, optarg, MAX_PATH - 1);
e7474978 544 break;
6c9ead29 545#if !defined(_WIN32) && !defined(_NETWARE)
6f4bc3b9
VK
546 case 'p': // PID file
547 strncpy(g_szPidFile, optarg, MAX_PATH - 1);
548 break;
6c9ead29 549#endif
e7474978
VK
550 case 'C': // Configuration check only
551 iAction = ACTION_CHECK_CONFIG;
552 break;
553 case 'v': // Print version and exit
554 printf("NetXMS Core Agent Version " AGENT_VERSION_STRING "\n");
555 iAction = ACTION_NONE;
556 break;
557#ifdef _WIN32
558 case 'I': // Install Windows service
559 iAction = ACTION_INSTALL_SERVICE;
560 break;
561 case 'R': // Remove Windows service
562 iAction = ACTION_REMOVE_SERVICE;
563 break;
564 case 's': // Start Windows service
565 iAction = ACTION_START_SERVICE;
566 break;
567 case 'S': // Stop Windows service
568 iAction = ACTION_STOP_SERVICE;
569 break;
1980ebfc
VK
570 case 'E': // Install Windows event source
571 iAction = ACTION_INSTALL_EVENT_SOURCE;
572 break;
573 case 'U': // Remove Windows event source
574 iAction = ACTION_REMOVE_EVENT_SOURCE;
575 break;
e7474978
VK
576#endif
577 case '?':
578 iAction = ACTION_NONE;
579 iExitCode = 1;
580 break;
581 default:
582 break;
583 }
584 }
585
586 // Do requested action
587 switch(iAction)
588 {
589 case ACTION_RUN_AGENT:
ae9cddaf 590 if (NxLoadConfig(g_szConfigFile, "", cfgTemplate, !(g_dwFlags & AF_DAEMON)) == NXCFG_ERR_OK)
e7474978 591 {
af4a704a
VK
592 if ((!stricmp(g_szLogFile, "{syslog}")) ||
593 (!stricmp(g_szLogFile, "{eventlog}")))
594 g_dwFlags |= AF_USE_SYSLOG;
595
e9580fef
VK
596#ifdef _WIN32
597 if (g_dwFlags & AF_DAEMON)
e7474978 598 {
e9580fef 599 InitService();
e7474978 600 }
e9580fef
VK
601 else
602 {
603 if (Initialize())
604 {
605 Main();
606 }
607 else
608 {
609 ConsolePrintf("Agent initialization failed\n");
610 CloseLog();
611 iExitCode = 3;
612 }
613 }
614#else /* _WIN32 */
3b1f0a0a 615#ifndef _NETWARE
e9580fef
VK
616 if (g_dwFlags & AF_DAEMON)
617 if (daemon(0, 0) == -1)
618 {
619 perror("Unable to setup itself as a daemon");
620 iExitCode = 4;
621 }
b492a277 622 // Setup signal handlers
ec07d64e
AK
623 //for(int i = 0; i < 32; i++)
624 // signal(i, SIG_IGN);
625 signal(SIGPIPE, SIG_IGN);
626 signal(SIGINT, OnSignal);
b492a277
VK
627 signal(SIGTERM, OnSignal);
628 signal(SIGSEGV, OnSignal);
3b1f0a0a 629#endif
e9580fef
VK
630 if (iExitCode == 0)
631 {
632 if (Initialize())
633 {
6f4bc3b9
VK
634#ifndef _NETWARE
635 FILE *fp;
636
637 // Write PID file
638 fp = fopen(g_szPidFile, "w");
639 if (fp != NULL)
640 {
641 fprintf(fp, "%d", getpid());
642 fclose(fp);
643 }
644#endif
e9580fef
VK
645 Main();
646 }
647 else
648 {
649 ConsolePrintf("Agent initialization failed\n");
650 CloseLog();
651 iExitCode = 3;
652 }
653 }
654#endif /* _WIN32 */
655
449e3da9 656 if (m_hCondShutdown != INVALID_CONDITION_HANDLE)
e9580fef 657 ConditionDestroy(m_hCondShutdown);
e7474978
VK
658 }
659 else
660 {
661 ConsolePrintf("Error loading configuration file\n");
662 iExitCode = 2;
663 }
664 break;
665 case ACTION_CHECK_CONFIG:
ae9cddaf 666 if (NxLoadConfig(g_szConfigFile, "", cfgTemplate, !(g_dwFlags & AF_DAEMON)) != NXCFG_ERR_OK)
e7474978
VK
667 {
668 ConsolePrintf("Configuration file check failed\n");
669 iExitCode = 2;
670 }
671 break;
672#ifdef _WIN32
673 case ACTION_INSTALL_SERVICE:
af4a704a 674 GetModuleFileName(GetModuleHandle(NULL), szModuleName, MAX_PATH);
ae9cddaf 675 InstallService(szModuleName, g_szConfigFile);
e7474978
VK
676 break;
677 case ACTION_REMOVE_SERVICE:
678 RemoveService();
679 break;
1980ebfc
VK
680 case ACTION_INSTALL_EVENT_SOURCE:
681 GetModuleFileName(GetModuleHandle(NULL), szModuleName, MAX_PATH);
682 InstallEventSource(szModuleName);
683 break;
684 case ACTION_REMOVE_EVENT_SOURCE:
685 RemoveEventSource();
686 break;
e7474978
VK
687 case ACTION_START_SERVICE:
688 StartAgentService();
689 break;
690 case ACTION_STOP_SERVICE:
691 StopAgentService();
692 break;
693#endif
694 default:
695 break;
696 }
697
ead6cccb
VK
698#ifdef _NETWARE
699 if ((iExitCode != 0) || (iAction == ACTION_NONE) ||
700 (iAction == ACTION_CHECK_CONFIG))
701 setscreenmode(SCR_NO_MODE);
702#endif
703
e7474978
VK
704 return iExitCode;
705}