Various fixes
[public/netxms.git] / src / agent / core / sysinfo.cpp
1 /* $Id: sysinfo.cpp,v 1.23 2007-05-26 10:42:19 victor Exp $ */
2 /*
3 ** NetXMS multiplatform core agent
4 ** Copyright (C) 2003, 2004 Victor Kirhenshtein
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License as published by
8 ** the Free Software Foundation; either version 2 of the License, or
9 ** (at your option) any later version.
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 **
20 ** File: sysinfo.cpp
21 **/
22
23 #include "nxagentd.h"
24
25 #if HAVE_SYS_UTSNAME_H
26 #include <sys/utsname.h>
27 #endif
28
29 #ifndef S_ISDIR
30 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
31 #endif
32
33
34 //
35 // Handler for Agent.Uptime parameter
36 //
37
38 LONG H_AgentUptime(char *cmd, char *arg, char *value)
39 {
40 ret_uint(value, (DWORD)(time(NULL) - g_tmAgentStartTime));
41 return SYSINFO_RC_SUCCESS;
42 }
43
44
45 //
46 // Helper function to GetDirInfo
47 //
48
49 LONG GetDirInfo(char *szPath, char *szPattern, bool bRecursive,
50 unsigned int &uFileCount, QWORD &llFileSize)
51 {
52 DIR *pDir = NULL;
53 struct dirent *pFile = NULL;
54 struct stat fileInfo;
55 char szFileName[MAX_PATH];
56 LONG nRet = SYSINFO_RC_SUCCESS;
57
58 if (stat(szPath, &fileInfo) == -1)
59 return SYSINFO_RC_ERROR;
60
61 // if this is just a file than simply return statistics
62 if (!S_ISDIR(fileInfo.st_mode))
63 {
64 if (MatchString(szPattern, szPath, FALSE))
65 {
66 llFileSize += (QWORD)fileInfo.st_size;
67 uFileCount++;
68 }
69
70 return nRet;
71 }
72
73 // this is a dir
74 pDir = opendir(szPath);
75 if (pDir != NULL)
76 {
77 while(1)
78 {
79 pFile = readdir(pDir);
80 if (pFile == NULL)
81 break;
82
83 if (!strcmp(pFile->d_name, ".") || !strcmp(pFile->d_name, ".."))
84 continue;
85
86 strcpy(szFileName, szPath);
87 strcat(szFileName, "/" );
88 strcat(szFileName, pFile->d_name);
89
90 // skip unaccessible entries
91 if (stat( szFileName, &fileInfo ) == -1)
92 continue;
93
94 if (S_ISDIR(fileInfo.st_mode) && bRecursive)
95 {
96 nRet = GetDirInfo(szFileName, szPattern, bRecursive, uFileCount, llFileSize);
97
98 if (nRet != SYSINFO_RC_SUCCESS)
99 break;
100 }
101
102 if (!S_ISDIR(fileInfo.st_mode) && MatchString(szPattern, pFile->d_name, FALSE))
103 {
104 llFileSize += (QWORD)fileInfo.st_size;
105 uFileCount++;
106 }
107 }
108 closedir(pDir);
109 }
110
111 return nRet;
112 }
113
114
115 //
116 // Handler for File.Size(*) and File.Count(*)
117 //
118
119 LONG H_DirInfo(char *cmd, char *arg, char *value)
120 {
121 char szPath[MAX_PATH], szPattern[MAX_PATH], szRecursive[10];
122 bool bRecursive = false;
123
124 unsigned int uFileCount = 0;
125 QWORD llFileSize = 0;
126 LONG nRet;
127
128 if (!NxGetParameterArg(cmd, 1, szPath, MAX_PATH))
129 return SYSINFO_RC_UNSUPPORTED;
130 if (!NxGetParameterArg(cmd, 2, szPattern, MAX_PATH))
131 return SYSINFO_RC_UNSUPPORTED;
132 if (!NxGetParameterArg(cmd, 3, szRecursive, 10))
133 return SYSINFO_RC_UNSUPPORTED;
134
135 // Recursion flag
136 bRecursive = ((atoi(szRecursive) != 0) || !_tcsicmp(szRecursive, _T("TRUE")));
137
138 // If pattern is omited use asterisk
139 if (szPattern[0] == 0)
140 strcpy(szPattern, "*");
141
142 nRet = GetDirInfo(szPath, szPattern, bRecursive, uFileCount, llFileSize);
143
144 switch(CAST_FROM_POINTER(arg, int))
145 {
146 case DIRINFO_FILE_SIZE:
147 ret_uint64(value, llFileSize);
148 break;
149 case DIRINFO_FILE_COUNT:
150 ret_uint(value, uFileCount);
151 break;
152 default:
153 nRet = SYSINFO_RC_UNSUPPORTED;
154 break;
155 }
156
157 return nRet;
158 }
159
160
161 //
162 // Calculate MD5 hash for file
163 //
164
165 LONG H_MD5Hash(char *cmd, char *arg, char *value)
166 {
167 char szFileName[MAX_PATH], szHashText[MD5_DIGEST_SIZE * 2 + 1];
168 BYTE hash[MD5_DIGEST_SIZE];
169 DWORD i;
170
171 if (!NxGetParameterArg(cmd, 1, szFileName, MAX_PATH))
172 return SYSINFO_RC_UNSUPPORTED;
173
174 if (!CalculateFileMD5Hash(szFileName, hash))
175 return SYSINFO_RC_UNSUPPORTED;
176
177 // Convert MD5 hash to text form
178 for(i = 0; i < MD5_DIGEST_SIZE; i++)
179 sprintf(&szHashText[i << 1], "%02x", hash[i]);
180
181 ret_string(value, szHashText);
182 return SYSINFO_RC_SUCCESS;
183 }
184
185
186 //
187 // Calculate SHA1 hash for file
188 //
189
190 LONG H_SHA1Hash(char *cmd, char *arg, char *value)
191 {
192 char szFileName[MAX_PATH], szHashText[SHA1_DIGEST_SIZE * 2 + 1];
193 BYTE hash[SHA1_DIGEST_SIZE];
194 DWORD i;
195
196 if (!NxGetParameterArg(cmd, 1, szFileName, MAX_PATH))
197 return SYSINFO_RC_UNSUPPORTED;
198
199 if (!CalculateFileSHA1Hash(szFileName, hash))
200 return SYSINFO_RC_UNSUPPORTED;
201
202 // Convert SHA1 hash to text form
203 for(i = 0; i < SHA1_DIGEST_SIZE; i++)
204 sprintf(&szHashText[i << 1], "%02x", hash[i]);
205
206 ret_string(value, szHashText);
207 return SYSINFO_RC_SUCCESS;
208 }
209
210
211 //
212 // Calculate CRC32 for file
213 //
214
215 LONG H_CRC32(char *cmd, char *arg, char *value)
216 {
217 char szFileName[MAX_PATH];
218 DWORD dwCRC32;
219
220 if (!NxGetParameterArg(cmd, 1, szFileName, MAX_PATH))
221 return SYSINFO_RC_UNSUPPORTED;
222
223 if (!CalculateFileCRC32(szFileName, &dwCRC32))
224 return SYSINFO_RC_UNSUPPORTED;
225
226 ret_uint(value, dwCRC32);
227 return SYSINFO_RC_SUCCESS;
228 }
229
230
231 //
232 // Handler for System.PlatformName
233 //
234
235 LONG H_PlatformName(char *cmd, char *arg, char *value)
236 {
237 LONG nResult = SYSINFO_RC_SUCCESS;
238
239 #if defined(_WIN32)
240
241 SYSTEM_INFO sysInfo;
242
243 GetSystemInfo(&sysInfo);
244 switch(sysInfo.wProcessorArchitecture)
245 {
246 case PROCESSOR_ARCHITECTURE_INTEL:
247 strcpy(value, "windows-i386");
248 break;
249 case PROCESSOR_ARCHITECTURE_MIPS:
250 strcpy(value, "windows-mips");
251 break;
252 case PROCESSOR_ARCHITECTURE_ALPHA:
253 strcpy(value, "windows-alpha");
254 break;
255 case PROCESSOR_ARCHITECTURE_PPC:
256 strcpy(value, "windows-ppc");
257 break;
258 case PROCESSOR_ARCHITECTURE_IA64:
259 strcpy(value, "windows-ia64");
260 break;
261 case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
262 strcpy(value, "windows-i386");
263 break;
264 case PROCESSOR_ARCHITECTURE_AMD64:
265 strcpy(value, "windows-x64");
266 break;
267 default:
268 strcpy(value, "windows-unknown");
269 break;
270 }
271
272 #elif defined(_NETWARE)
273
274 // NetWare only exists on Intel x86 CPU,
275 // so there are nothing to detect
276 strcpy(value, "netware-i386");
277
278 #elif HAVE_UNAME
279
280 struct utsname info;
281
282 if (uname(&info) != -1)
283 {
284 #ifdef _AIX
285 // Assume that we are running on PowerPC
286 sprintf(value, "%s-powerpc", info.sysname);
287 #else
288 sprintf(value, "%s-%s", info.sysname, info.machine);
289 #endif
290 }
291 else
292 {
293 DebugPrintf(INVALID_INDEX, "uname() failed: %s", strerror(errno));
294 nResult = SYSINFO_RC_ERROR;
295 }
296
297 #else
298
299 // Finally, we don't know a way to detect platform
300 strcpy(value, "unknown");
301
302 #endif
303
304 // Add user-configurable platform name suffix
305 if ((nResult == SYSINFO_RC_SUCCESS) && (g_szPlatformSuffix[0] != 0))
306 {
307 if (g_szPlatformSuffix[0] != '-')
308 strcat(value, "-");
309 strcat(value, g_szPlatformSuffix);
310 }
311
312 return nResult;
313 }
314
315
316 //
317 // Handler for File.Time.* parameters
318 //
319
320 LONG H_FileTime(char *cmd, char *arg, char *value)
321 {
322 char szFilePath[MAX_PATH];
323 LONG nRet = SYSINFO_RC_SUCCESS;
324 struct stat fileInfo;
325
326 if (!NxGetParameterArg(cmd, 1, szFilePath, MAX_PATH))
327 return SYSINFO_RC_UNSUPPORTED;
328
329 if (stat(szFilePath, &fileInfo) == -1)
330 return SYSINFO_RC_ERROR;
331
332 switch(CAST_FROM_POINTER(arg, int))
333 {
334 case FILETIME_ATIME:
335 #ifdef _NETWARE
336 ret_uint64(value, fileInfo.st_atime.tv_sec);
337 #else
338 ret_uint64(value, fileInfo.st_atime);
339 #endif
340 break;
341 case FILETIME_MTIME:
342 #ifdef _NETWARE
343 ret_uint64(value, fileInfo.st_mtime.tv_sec);
344 #else
345 ret_uint64(value, fileInfo.st_mtime);
346 #endif
347 break;
348 case FILETIME_CTIME:
349 #ifdef _NETWARE
350 ret_uint64(value, fileInfo.st_ctime.tv_sec);
351 #else
352 ret_uint64(value, fileInfo.st_ctime);
353 #endif
354 break;
355 default:
356 nRet = SYSINFO_RC_UNSUPPORTED;
357 break;
358 }
359
360 return nRet;
361 }