- All component locks moved to memory
[public/netxms.git] / src / server / core / config.cpp
1 /*
2 ** Project X - Network Management System
3 ** Copyright (C) 2003 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 ** $module: config.cpp
20 **
21 **/
22
23 #include "nms_core.h"
24
25
26 //
27 // Help text
28 //
29
30 static char help_text[]="NetXMS Server Version " NETXMS_VERSION_STRING "\n"
31 "Copyright (c) 2003 SecurityProjects.org\n\n"
32 "Usage: netxmsd [<options>] <command>\n\n"
33 "Valid options are:\n"
34 " --config <file> : Set non-default configuration file\n"
35 " : Default is " DEFAULT_CONFIG_FILE "\n"
36 " --debug-all : Turn on all possible debug output\n"
37 " --debug-actions : Print debug information for event actions.\n"
38 " --debug-cscp : Print client-server communication protocol debug\n"
39 " : information to console.\n"
40 " --debug-dc : Print data collection debug information to console.\n"
41 " --debug-discovery : Print network discovery debug information to console.\n"
42 " --debug-events : Print events to console.\n"
43 " --debug-housekeeper : Print debug information for housekeeping thread.\n"
44 " --debug-locks : Print debug information about component locking.\n"
45 " --debug-snmp : Print SNMP debug information.\n"
46 " --dump-sql : Dump all SQL queries to log.\n"
47 #ifndef _WIN32
48 " --pid-file <file> : Specify pid file.\n"
49 #endif
50 "\n"
51 "Valid commands are:\n"
52 " check-config : Check configuration file syntax\n"
53 #ifdef _WIN32
54 " install : Install Win32 service\n"
55 " install-events : Install Win32 event source\n"
56 #endif
57 " help : Display help and exit\n"
58 #ifdef _WIN32
59 " remove : Remove Win32 service\n"
60 " remove-events : Remove Win32 event source\n"
61 #endif
62 " standalone : Run in standalone mode (not as service)\n"
63 " version : Display version and exit\n"
64 "\n"
65 "NOTE: All debug options will work only in standalone mode.\n\n";
66
67
68 //
69 // Load and parse configuration file
70 // Returns TRUE on success and FALSE on failure
71 //
72
73 static NX_CFG_TEMPLATE m_cfgTemplate[] =
74 {
75 { "DBDriver", CT_STRING, 0, 0, MAX_PATH, 0, g_szDbDriver },
76 { "DBDrvParams", CT_STRING, 0, 0, MAX_PATH, 0, g_szDbDrvParams },
77 { "DBLogin", CT_STRING, 0, 0, MAX_DB_LOGIN, 0, g_szDbLogin },
78 { "DBName", CT_STRING, 0, 0, MAX_DB_NAME, 0, g_szDbName },
79 { "DBPassword", CT_STRING, 0, 0, MAX_DB_PASSWORD, 0, g_szDbPassword },
80 { "DBServer", CT_STRING, 0, 0, MAX_PATH, 0, g_szDbServer },
81 { "LogFailedSQLQueries", CT_BOOLEAN, 0, 0, AF_LOG_SQL_ERRORS, 0, &g_dwFlags },
82 { "LogFile", CT_STRING, 0, 0, MAX_PATH, 0, g_szLogFile },
83 { "", CT_END_OF_LIST, 0, 0, 0, 0, NULL }
84 };
85
86 BOOL LoadConfig(void)
87 {
88 BOOL bSuccess = FALSE;
89
90 if (IsStandalone())
91 printf("Using configuration file \"%s\"\n", g_szConfigFile);
92
93 if (NxLoadConfig(g_szConfigFile, "", m_cfgTemplate, IsStandalone()) == NXCFG_ERR_OK)
94 {
95 if ((!stricmp(g_szLogFile,"{EventLog}")) ||
96 (!stricmp(g_szLogFile,"{syslog}")))
97 {
98 g_dwFlags |= AF_USE_EVENT_LOG;
99 }
100 else
101 {
102 g_dwFlags &= ~AF_USE_EVENT_LOG;
103 }
104 bSuccess = TRUE;
105 }
106 return bSuccess;
107 }
108
109
110 //
111 // Parse command line
112 // Returns TRUE on success and FALSE on failure
113 //
114
115 BOOL ParseCommandLine(int argc, char *argv[])
116 {
117 int i;
118
119 for(i = 1; i < argc; i++)
120 {
121 if (!strcmp(argv[i], "help")) // Display help and exit
122 {
123 printf(help_text);
124 return FALSE;
125 }
126 else if (!strcmp(argv[i], "version")) // Display version and exit
127 {
128 printf("NMS Version " NETXMS_VERSION_STRING " Build of " __DATE__ "\n");
129 return FALSE;
130 }
131 else if (!strcmp(argv[i], "--config")) // Config file
132 {
133 i++;
134 strcpy(g_szConfigFile, argv[i]); // Next word should contain name of the config file
135 }
136 #ifndef _WIN32
137 else if (!strcmp(argv[i], "--pid-file")) // PID file
138 {
139 i++;
140 strcpy(g_szPIDFile, argv[i]); // Next word should contain name of the PID file
141 }
142 #endif
143 else if (!strcmp(argv[i], "--debug-all"))
144 {
145 g_dwFlags |= AF_DEBUG_ALL;
146 }
147 else if (!strcmp(argv[i], "--debug-events"))
148 {
149 g_dwFlags |= AF_DEBUG_EVENTS;
150 }
151 else if (!strcmp(argv[i], "--debug-cscp"))
152 {
153 g_dwFlags |= AF_DEBUG_CSCP;
154 }
155 else if (!strcmp(argv[i], "--debug-discovery"))
156 {
157 g_dwFlags |= AF_DEBUG_DISCOVERY;
158 }
159 else if (!strcmp(argv[i], "--debug-dc"))
160 {
161 g_dwFlags |= AF_DEBUG_DC;
162 }
163 else if (!strcmp(argv[i], "--debug-locks"))
164 {
165 g_dwFlags |= AF_DEBUG_LOCKS;
166 }
167 else if (!strcmp(argv[i], "--debug-housekeeper"))
168 {
169 g_dwFlags |= AF_DEBUG_HOUSEKEEPER;
170 }
171 else if (!strcmp(argv[i], "--debug-actions"))
172 {
173 g_dwFlags |= AF_DEBUG_ACTIONS;
174 }
175 else if (!strcmp(argv[i], "--debug-snmp"))
176 {
177 g_dwFlags |= AF_DEBUG_SNMP;
178 }
179 else if (!strcmp(argv[i], "--dump-sql"))
180 {
181 g_dwFlags |= AF_DEBUG_SQL;
182 }
183 else if (!strcmp(argv[i], "check-config"))
184 {
185 g_dwFlags |= AF_STANDALONE;
186 printf("Checking configuration file (%s):\n\n", g_szConfigFile);
187 LoadConfig();
188 return FALSE;
189 }
190 else if (!strcmp(argv[i], "standalone")) // Run in standalone mode
191 {
192 g_dwFlags |= AF_STANDALONE;
193 return TRUE;
194 }
195 #ifdef _WIN32
196 else if ((!strcmp(argv[i], "install"))||
197 (!strcmp(argv[i], "install-events")))
198 {
199 char exePath[MAX_PATH], dllPath[MAX_PATH], *ptr;
200
201 ptr = strrchr(argv[0], '\\');
202 if (ptr != NULL)
203 ptr++;
204 else
205 ptr = argv[0];
206
207 _fullpath(exePath, ptr, 255);
208
209 if (stricmp(&exePath[strlen(exePath)-4], ".exe"))
210 strcat(exePath, ".exe");
211 strcpy(dllPath, exePath);
212 ptr = strrchr(dllPath, '\\');
213 if (ptr != NULL) // Shouldn't be NULL
214 {
215 ptr++;
216 strcpy(ptr, "libnxsrv.dll");
217 }
218
219 if (!strcmp(argv[i], "install"))
220 InstallService(exePath, dllPath);
221 else
222 InstallEventSource(dllPath);
223 return FALSE;
224 }
225 else if (!strcmp(argv[i], "remove"))
226 {
227 RemoveService();
228 return FALSE;
229 }
230 else if (!strcmp(argv[i], "remove-events"))
231 {
232 RemoveEventSource();
233 return FALSE;
234 }
235 else if (!strcmp(argv[i], "start"))
236 {
237 StartCoreService();
238 return FALSE;
239 }
240 else if (!strcmp(argv[i], "stop"))
241 {
242 StopCoreService();
243 return FALSE;
244 }
245 #endif /* _WIN32 */
246 else
247 {
248 printf("ERROR: Invalid command line argument\n\n");
249 return FALSE;
250 }
251 }
252
253 return TRUE;
254 }
255
256
257 //
258 // Read string value from configuration table
259 //
260
261 BOOL ConfigReadStr(char *szVar, char *szBuffer, int iBufSize, const char *szDefault)
262 {
263 DB_RESULT hResult;
264 char szQuery[256];
265 BOOL bSuccess = FALSE;
266
267 strncpy(szBuffer, szDefault, iBufSize);
268 if (strlen(szVar) > 127)
269 return FALSE;
270
271 sprintf(szQuery, "SELECT var_value FROM config WHERE var_name='%s'", szVar);
272 hResult = DBSelect(g_hCoreDB, szQuery);
273 if (hResult == 0)
274 return FALSE;
275
276 if (DBGetNumRows(hResult) > 0)
277 {
278 strncpy(szBuffer, DBGetField(hResult, 0, 0), iBufSize - 1);
279 bSuccess = TRUE;
280 }
281
282 DBFreeResult(hResult);
283 return bSuccess;
284 }
285
286
287 //
288 // Read integer value from configuration table
289 //
290
291 int ConfigReadInt(char *szVar, int iDefault)
292 {
293 char szBuffer[64];
294
295 if (ConfigReadStr(szVar, szBuffer, 64, ""))
296 return strtol(szBuffer, NULL, 0);
297 else
298 return iDefault;
299 }
300
301
302 //
303 // Read unsigned long value from configuration table
304 //
305
306 DWORD ConfigReadULong(char *szVar, DWORD dwDefault)
307 {
308 char szBuffer[64];
309
310 if (ConfigReadStr(szVar, szBuffer, 64, ""))
311 return strtoul(szBuffer, NULL, 0);
312 else
313 return dwDefault;
314 }
315
316
317 //
318 // Write string value to configuration table
319 //
320
321 BOOL ConfigWriteStr(char *szVar, char *szValue, BOOL bCreate)
322 {
323 DB_RESULT hResult;
324 char szQuery[1024];
325 BOOL bVarExist = FALSE;
326
327 if (strlen(szVar) > 127)
328 return FALSE;
329
330 // Check for variable existence
331 sprintf(szQuery, "SELECT var_value FROM config WHERE var_name='%s'", szVar);
332 hResult = DBSelect(g_hCoreDB, szQuery);
333 if (hResult != 0)
334 {
335 if (DBGetNumRows(hResult) > 0)
336 bVarExist = TRUE;
337 DBFreeResult(hResult);
338 }
339
340 // Don't create non-existing variable if creation flag not set
341 if (!bCreate && !bVarExist)
342 return FALSE;
343
344 // Create or update variable value
345 if (bVarExist)
346 sprintf(szQuery, "UPDATE config SET var_value='%s' WHERE var_name='%s'", szValue, szVar);
347 else
348 sprintf(szQuery, "INSERT INTO config (var_name,var_value,is_visible,"
349 "need_server_restart) VALUES ('%s','%s',0,0)", szVar, szValue);
350 return DBQuery(g_hCoreDB, szQuery);
351 }
352
353
354 //
355 // Write integer value to configuration table
356 //
357
358 BOOL ConfigWriteInt(char *szVar, int iValue, BOOL bCreate)
359 {
360 char szBuffer[64];
361
362 sprintf(szBuffer, "%ld", iValue);
363 return ConfigWriteStr(szVar, szBuffer, bCreate);
364 }
365
366
367 //
368 // Write unsigned long value to configuration table
369 //
370
371 BOOL ConfigWriteULong(char *szVar, DWORD dwValue, BOOL bCreate)
372 {
373 char szBuffer[64];
374
375 sprintf(szBuffer, "%lu", dwValue);
376 return ConfigWriteStr(szVar, szBuffer, bCreate);
377 }