Commit | Line | Data |
---|---|---|
9a19737f VK |
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 | ||
b7271ccb | 30 | static char help_text[]="NetXMS Server Version " NETXMS_VERSION_STRING "\n" |
9a19737f | 31 | "Copyright (c) 2003 SecurityProjects.org\n\n" |
b7271ccb | 32 | "Usage: netxmsd [<options>] <command>\n\n" |
9a19737f | 33 | "Valid options are:\n" |
e77547c2 VK |
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" | |
4d5a05a0 | 37 | " --debug-actions : Print debug information for event actions.\n" |
e77547c2 VK |
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" | |
b54b2b11 | 44 | " --debug-locks : Print debug information about component locking.\n" |
3aeed82c | 45 | " --debug-snmp : Print SNMP debug information.\n" |
3679d89a | 46 | " --dump-sql : Dump all SQL queries to log.\n" |
9e9d381c VK |
47 | #ifndef _WIN32 |
48 | " --pid-file <file> : Specify pid file.\n" | |
49 | #endif | |
9a19737f VK |
50 | "\n" |
51 | "Valid commands are:\n" | |
e77547c2 | 52 | " check-config : Check configuration file syntax\n" |
9a19737f | 53 | #ifdef _WIN32 |
e77547c2 VK |
54 | " install : Install Win32 service\n" |
55 | " install-events : Install Win32 event source\n" | |
9a19737f | 56 | #endif |
e77547c2 | 57 | " help : Display help and exit\n" |
9a19737f | 58 | #ifdef _WIN32 |
e77547c2 VK |
59 | " remove : Remove Win32 service\n" |
60 | " remove-events : Remove Win32 event source\n" | |
9a19737f | 61 | #endif |
e77547c2 VK |
62 | " standalone : Run in standalone mode (not as service)\n" |
63 | " version : Display version and exit\n" | |
7fdc8a45 VK |
64 | "\n" |
65 | "NOTE: All debug options will work only in standalone mode.\n\n"; | |
9a19737f VK |
66 | |
67 | ||
68 | // | |
69 | // Load and parse configuration file | |
4385fa12 | 70 | // Returns TRUE on success and FALSE on failure |
9a19737f VK |
71 | // |
72 | ||
9a30b4fb VK |
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 | ||
4385fa12 | 86 | BOOL LoadConfig(void) |
9a19737f | 87 | { |
9a30b4fb | 88 | BOOL bSuccess = FALSE; |
4385fa12 VK |
89 | |
90 | if (IsStandalone()) | |
91 | printf("Using configuration file \"%s\"\n", g_szConfigFile); | |
92 | ||
6849d9be | 93 | if (NxLoadConfig(g_szConfigFile, "", m_cfgTemplate, IsStandalone()) == NXCFG_ERR_OK) |
4385fa12 | 94 | { |
9a30b4fb VK |
95 | if ((!stricmp(g_szLogFile,"{EventLog}")) || |
96 | (!stricmp(g_szLogFile,"{syslog}"))) | |
4385fa12 | 97 | { |
9a30b4fb | 98 | g_dwFlags |= AF_USE_EVENT_LOG; |
78bf9c68 | 99 | } |
4385fa12 VK |
100 | else |
101 | { | |
9a30b4fb | 102 | g_dwFlags &= ~AF_USE_EVENT_LOG; |
4385fa12 | 103 | } |
9a30b4fb | 104 | bSuccess = TRUE; |
4385fa12 | 105 | } |
9a30b4fb | 106 | return bSuccess; |
9a19737f VK |
107 | } |
108 | ||
109 | ||
110 | // | |
111 | // Parse command line | |
4385fa12 | 112 | // Returns TRUE on success and FALSE on failure |
9a19737f VK |
113 | // |
114 | ||
4385fa12 | 115 | BOOL ParseCommandLine(int argc, char *argv[]) |
9a19737f VK |
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); | |
4385fa12 | 124 | return FALSE; |
9a19737f VK |
125 | } |
126 | else if (!strcmp(argv[i], "version")) // Display version and exit | |
127 | { | |
79fa4ddd | 128 | printf("NMS Version " NETXMS_VERSION_STRING " Build of " __DATE__ "\n"); |
4385fa12 | 129 | return FALSE; |
9a19737f VK |
130 | } |
131 | else if (!strcmp(argv[i], "--config")) // Config file | |
132 | { | |
133 | i++; | |
4385fa12 | 134 | strcpy(g_szConfigFile, argv[i]); // Next word should contain name of the config file |
9a19737f | 135 | } |
9e9d381c VK |
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 | |
3e4e127f VK |
143 | else if (!strcmp(argv[i], "--debug-all")) |
144 | { | |
145 | g_dwFlags |= AF_DEBUG_ALL; | |
146 | } | |
f00307b7 VK |
147 | else if (!strcmp(argv[i], "--debug-events")) |
148 | { | |
149 | g_dwFlags |= AF_DEBUG_EVENTS; | |
150 | } | |
4a4afbd0 VK |
151 | else if (!strcmp(argv[i], "--debug-cscp")) |
152 | { | |
153 | g_dwFlags |= AF_DEBUG_CSCP; | |
154 | } | |
7fdc8a45 VK |
155 | else if (!strcmp(argv[i], "--debug-discovery")) |
156 | { | |
157 | g_dwFlags |= AF_DEBUG_DISCOVERY; | |
158 | } | |
3e4e127f VK |
159 | else if (!strcmp(argv[i], "--debug-dc")) |
160 | { | |
161 | g_dwFlags |= AF_DEBUG_DC; | |
162 | } | |
b54b2b11 VK |
163 | else if (!strcmp(argv[i], "--debug-locks")) |
164 | { | |
165 | g_dwFlags |= AF_DEBUG_LOCKS; | |
166 | } | |
e77547c2 VK |
167 | else if (!strcmp(argv[i], "--debug-housekeeper")) |
168 | { | |
169 | g_dwFlags |= AF_DEBUG_HOUSEKEEPER; | |
170 | } | |
4d5a05a0 VK |
171 | else if (!strcmp(argv[i], "--debug-actions")) |
172 | { | |
173 | g_dwFlags |= AF_DEBUG_ACTIONS; | |
174 | } | |
3aeed82c VK |
175 | else if (!strcmp(argv[i], "--debug-snmp")) |
176 | { | |
177 | g_dwFlags |= AF_DEBUG_SNMP; | |
178 | } | |
3679d89a VK |
179 | else if (!strcmp(argv[i], "--dump-sql")) |
180 | { | |
181 | g_dwFlags |= AF_DEBUG_SQL; | |
182 | } | |
9a19737f VK |
183 | else if (!strcmp(argv[i], "check-config")) |
184 | { | |
4385fa12 VK |
185 | g_dwFlags |= AF_STANDALONE; |
186 | printf("Checking configuration file (%s):\n\n", g_szConfigFile); | |
9a19737f | 187 | LoadConfig(); |
4385fa12 | 188 | return FALSE; |
9a19737f | 189 | } |
9a19737f VK |
190 | else if (!strcmp(argv[i], "standalone")) // Run in standalone mode |
191 | { | |
4385fa12 | 192 | g_dwFlags |= AF_STANDALONE; |
9a19737f VK |
193 | return TRUE; |
194 | } | |
c4495b00 | 195 | #ifdef _WIN32 |
9a19737f VK |
196 | else if ((!strcmp(argv[i], "install"))|| |
197 | (!strcmp(argv[i], "install-events"))) | |
198 | { | |
9cc9ea72 | 199 | char exePath[MAX_PATH], dllPath[MAX_PATH], *ptr; |
9a19737f VK |
200 | |
201 | ptr = strrchr(argv[0], '\\'); | |
202 | if (ptr != NULL) | |
203 | ptr++; | |
204 | else | |
205 | ptr = argv[0]; | |
206 | ||
9cc9ea72 | 207 | _fullpath(exePath, ptr, 255); |
9a19737f | 208 | |
9cc9ea72 VK |
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 | } | |
9a19737f VK |
218 | |
219 | if (!strcmp(argv[i], "install")) | |
9cc9ea72 | 220 | InstallService(exePath, dllPath); |
9a19737f | 221 | else |
9cc9ea72 | 222 | InstallEventSource(dllPath); |
9a19737f VK |
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"); | |
4385fa12 | 249 | return FALSE; |
9a19737f VK |
250 | } |
251 | } | |
252 | ||
4385fa12 | 253 | return TRUE; |
9a19737f | 254 | } |
3a2f672c VK |
255 | |
256 | ||
257 | // | |
258 | // Read string value from configuration table | |
259 | // | |
260 | ||
62d11997 | 261 | BOOL ConfigReadStr(char *szVar, char *szBuffer, int iBufSize, const char *szDefault) |
3a2f672c VK |
262 | { |
263 | DB_RESULT hResult; | |
264 | char szQuery[256]; | |
265 | BOOL bSuccess = FALSE; | |
266 | ||
b4895bbe | 267 | strncpy(szBuffer, szDefault, iBufSize); |
3a2f672c VK |
268 | if (strlen(szVar) > 127) |
269 | return FALSE; | |
270 | ||
31115ff9 | 271 | sprintf(szQuery, "SELECT var_value FROM config WHERE var_name='%s'", szVar); |
3a2f672c VK |
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 | } | |
7084ac81 VK |
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 | ||
e77547c2 VK |
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 | ||
7084ac81 VK |
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 | |
31115ff9 | 331 | sprintf(szQuery, "SELECT var_value FROM config WHERE var_name='%s'", szVar); |
7084ac81 VK |
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) | |
31115ff9 | 346 | sprintf(szQuery, "UPDATE config SET var_value='%s' WHERE var_name='%s'", szValue, szVar); |
7084ac81 | 347 | else |
540da048 VK |
348 | sprintf(szQuery, "INSERT INTO config (var_name,var_value,is_visible," |
349 | "need_server_restart) VALUES ('%s','%s',0,0)", szVar, szValue); | |
7084ac81 VK |
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 | } | |
e77547c2 VK |
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 | } |